@Parcelize аннотация вместе с наследованием

Я не могу создать общую структуру вместе с аннотацией @parcelize. Я хочу, чтобы конструктор использовался как конструктор для Jason, Room и Parcelable.

Предположим, у нас есть класс

@Parcelize
class Food(var taste: String = "")

Теперь два решения, которые приходят мне в голову сначала

1. жалуется, что вкус должен быть var или val, чтобы иметь пригодный для использования конструктор Parceable

@Parcelize
class FastFood(var callory:String = "", taste: String): Food(taste) // error

2. жалуется, что я должен явно овверидировать вкус - так каковы преимущества полиморфизма?

@Parcelize
class FastFood(var callory: String = "", var taste: String): Food(taste) // error

Как я могу эффективно использовать наследование вместе с вашей библиотекой?

4 ответа

В Kotlin, если вы добавите значение в конструктор 'val' или 'var', оно станет свойством класса. Чтобы использовать Parceable, вам нужно добавить его, потому что без него Parcelable.Creator не сможет получить к нему доступ. Затем вам нужно добавить модификатор 'open' к классу Food и к свойству 'вкус', потому что в Kotlin все final по умолчанию, так что вы сможете переопределить значение вкуса.

@Parcelize
open class Food(open val taste: String)

@Parcelize
class FastFood(var callory:String = "", override val taste: String): Food(taste)

Я не смог найти идеального решения с помощью @Parcelize, но есть два слегка ошибочных способа.

1) Сделайте базовый класс абстрактным и используйте только @Parcelize в дочерних элементах. Это означает, что у вас не может быть экземпляра родительского объекта, но иногда это нормально. Если вы можете себе это позволить, это эффективное решение.

abstract class Food : Parcelable {
    abstract var taste: String
}

@Parcelize
class FastFood(var callory: String = "", override var taste: String = "") : Food()

2) Возможно, вам нужно создать экземпляр родителя. Один из способов сделать это - сделать базовый класс не родительским, а родительским для родительского и дочернего классов. К сожалению, это немного нарушает иерархию классов, и FastFood не будет разновидностью еды, а скорее будет разновидностью BaseFood.

abstract class BaseFood : Parcelable {
    abstract var taste: String
}

@Parcelize
class Food(override var taste: String = "") : BaseFood()

@Parcelize
class FastFood(var callory: String = "", override var taste: String = "") : BaseFood()

По состоянию на декабрь 2021 года проблема все еще существует, я не могу использовать наследование с @Parcelize.

Родительский класс:

      import android.os.Parcelable
import kotlinx.parcelize.Parcelize

@Parcelize
open class Parent (
    var parentString : String
) : Parcelable {
    constructor(): this("")
}

Дочерний класс (который наследует родительский класс)

      import android.os.Parcelable
import kotlinx.parcelize.Parcelize

@Parcelize
data class Child (
    var childString : String
) : Parent(), Parcelable {
    constructor() : this("")
}

Я отправляю объект дочернего класса из ActivityA в ActivityB

Код ActivityA: (Отправитель)

      val child = Child()
child.childString = "THIS IS CHILD"
child.parentString = "THIS IS PARENT"
val intent = Intent(this, ActivityB::class.java)
val bundle = Bundle()
bundle.putParcelable("parcel", child)
intent.putExtra("bundle", bundle)
startActivity(intent)

Код ActivityB: (Получатель)

      val bundle = intent.getBundleExtra("bundle")
val child = bundle?.getParcelable<Child>("parcel") as Child
Log.e("Child Class c", child.childString) //THIS IS CHILD
Log.e("Parent Class p", child.parentString) //"" <- issue

child.parentString = "" вместо ЭТО РОДИТЕЛЬ , который является проблемой @Parcelize

Основываясь на предложениях из проблемы YouTrack , мне удалось использовать обходной путь, основанный наinterfaceдекларация примерно такая:

      interface MyInterface {
    val value01: String
    val value02: String
}

@Parcelize
data class Child01(
    override val value01: String,
    override val value02: String
) : MyInterface, Parcelable

@Parcelize
data class Child02(
    override val value01: String,
    override val value02: String
) : MyInterface, Parcelable
Другие вопросы по тегам