【问题标题】:Subclassing Room Entities子类化房间实体
【发布时间】:2018-08-15 17:39:07
【问题描述】:

有没有办法对 Room 中的实体进行子类化?

我有车entity

@Entity(tableName = "cars")
data class Car(
        @PrimaryKey @ColumnInfo(name = "vin") val vin: String,
        val manufacturer: String,
        val model: String,
        val color: String,
        val modelYear: Int,
        val trim: String = ""
) {

    override fun toString() = String.format("%s %s %s %s", modelYear, manufacturer, model, trim)
}

但我想将manufacturermodelmodelYear 移动到Vehicle 实体并让Car 继承自它。

我尝试使用这些字段创建Vehicle 实体并使用data class Car : Vehicle,但无法编译。错误是This type is final and cannot be inherited

【问题讨论】:

    标签: android kotlin android-room


    【解决方案1】:

    kotlin中,默认所有类都是final的。

    来自Docs

    类上的 open 注解与 Java 的 final 相反:它 允许其他人从这个类继承。 By default, all classes in Kotlin are final,对应 Effective Java,第 3 版, 第 19 条:设计和记录继承或禁止继承。

    所以你需要添加open关键字所以使用

    open class Vehicle(..){...}
    

    然后

    data class Car(...): Vehicle(..){}
    

    旁注:如果您尝试继承 data 类,那么您就不能在 Kotlin 中继承 data 类,因为数据类中的 copy 之类的方法是最终的,不能被子类覆盖(在这种情况下是data 类,所以它会自动执行)并且当类层次结构随着不同的数据成员呈指数增长时,很难实现像equals 这样的其他方法,尽管您可以通过创建非数据父类或abstract 来避免所有这些冲突类

    【讨论】:

    • 有趣的旁注。我刚刚在另一篇 SO 帖子中读到了同样的内容。我想我可以使用abstract,但它并没有提供我希望的相同好处。为什么它是这样设计的,或者仅仅是 Kotlin 的限制,有什么原因吗?
    • 是的 abstract ,它只是一个 Is-a 关系和数据类继承,一个原因是复制方法覆盖是不可能的,其他是不可能的,参见示例 data class Vehicle(val model:String); data class FutureCar(val engine:FancyEngine,val body:BodyBuilderFactory,val model:String):Vehcile(model); 所以在这种情况下尽管允许覆盖,但默认情况下很难实现对 Vehicle 类的其他子项的 equals,但规范设计者认为这可能会破坏拥有数据类的目的并增加更多含义
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-10-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多