如何在Kotlin中结合Kotlinx序列化正确使用类继承

如何在Kotlin中结合Kotlinx序列化正确使用类继承,kotlin,kotlinx.serialization,Kotlin,Kotlinx.serialization,我有一个简单的层次结构,包含以下内容: 抽象类基项 打开类项:BaseItem 类背包:物品 它们都应该使用Kotlinx序列化。在我添加背包类之前,一切都很顺利。 我使用Kotlinx序列化的版本1.4.32 下面是我的类层次结构的详细信息 //Items.kt @可序列化 密封类基本项{ 抽象值id:String 抽象值类型:ItemType 摘要:字符串 抽象var模型:String 抽象var-imageLink:String 抽象变量:可变列表 抽象变量隐式属性:可变列表 抽象变量

我有一个简单的层次结构,包含以下内容:

  • 抽象类基项
  • 打开类项:BaseItem
  • 类背包:物品
它们都应该使用Kotlinx序列化。在我添加
背包
类之前,一切都很顺利。 我使用Kotlinx序列化的版本
1.4.32

下面是我的类层次结构的详细信息

//Items.kt
@可序列化
密封类基本项{
抽象值id:String
抽象值类型:ItemType
摘要:字符串
抽象var模型:String
抽象var-imageLink:String
抽象变量:可变列表
抽象变量隐式属性:可变列表
抽象变量详细信息:可变映射
}
@可序列化
公开课项目(
重写val id:String=UUID.randomUUID().toString(),
覆盖值类型:ItemType=ItemType.UNDEFINED,
覆盖变量brand:String,
覆盖变量模型:字符串,
重写var imageLink:字符串,
覆盖变量特性:可变列表,
重写变量implicitTraits:MutableList,
覆盖变量详细信息:可变映射,
):BaseItem()
@可序列化//标记为不正确
背包(
品牌:String,
型号:String,
imageLink:String,
特点:可变列表,
隐式属性:可变列表,
详细信息:可变地图,
变量卷:Int
):项目(
type=ItemType.BACKPACK,
品牌=品牌,
模型=模型,
imageLink=imageLink,
特质=特质,
implicitTraits=implicitTraits,
细节=细节
)
IDE向我显示了附加到
背包
类的
@序列化
注释的以下消息

This class is not serializable automatically because it has primary constructor parameters that are not properties
我无法从以下方面找到正确的工作方式:

为了使类的层次结构可序列化,父类中的属性必须标记为抽象,从而使[parent]类也抽象

发件人:

为了使类的层次结构可序列化,父类中的属性必须标记为抽象,从而使[parent]类也抽象


这是因为构造函数的参数没有定义为类的属性。要将参数定义为属性,必须将
val
var
添加到参数中。这将解决您当前收到的错误消息:

@Serializable
class Backpack(
    override var brand: String,
    override var model: String,
    override var imageLink: String,
    override var traits: MutableList<Trait>,
    override var implicitTraits: MutableList<Trait>,
    override var details: MutableMap<String, String>,
    var volume: Int
) : Item(
    type = ItemType.BACKPACK,
    brand = brand,
    model = model,
    imageLink = imageLink,
    traits = traits,
    implicitTraits = implicitTraits,
    details = details
)

顺便说一句,我从
BaseItem
中删除了
@Serializable
,因为它是不必要的,因为该类无论如何都是抽象的,因此根本不会被序列化。我还创建了您的类
数据类
,因为我的印象是这些类基本上是用来保存数据的,而这些类通常是用
数据类
实现的。我留下了许多
var
,我不知道其中的原因,但我这边的一个小提示是,您应该更喜欢
val
而不是
var
,尤其是在
数据类中。在这个场景中,<>代码> var >代码对我来说就像是代码的味道,您可能需要考虑使用<代码> Valu/Cord>。Kotlin页面本身就是一个很好的例子:

这是因为构造函数的参数没有定义为类的属性。要将参数定义为属性,必须将
val
var
添加到参数中。这将解决您当前收到的错误消息:

@Serializable
class Backpack(
    override var brand: String,
    override var model: String,
    override var imageLink: String,
    override var traits: MutableList<Trait>,
    override var implicitTraits: MutableList<Trait>,
    override var details: MutableMap<String, String>,
    var volume: Int
) : Item(
    type = ItemType.BACKPACK,
    brand = brand,
    model = model,
    imageLink = imageLink,
    traits = traits,
    implicitTraits = implicitTraits,
    details = details
)

顺便说一句,我从
BaseItem
中删除了
@Serializable
,因为它是不必要的,因为该类无论如何都是抽象的,因此根本不会被序列化。我还创建了您的类
数据类
,因为我的印象是这些类基本上是用来保存数据的,而这些类通常是用
数据类
实现的。我留下了许多
var
,我不知道其中的原因,但我这边的一个小提示是,您应该更喜欢
val
而不是
var
,尤其是在
数据类中。在这个场景中,<>代码> var >代码对我来说就像是代码的味道,您可能需要考虑使用<代码> Valu/Cord>。Kotlin页面本身就是一个很好的写手:

条目
但是不打算抽象使用-代码库中已经有了它的实例,应该保持这种状态way@xetra11在这种情况下,
BackPack
不能扩展
Item
,也不能序列化。您可能需要按照Big_Foot1989的建议调整您的类层次结构。
但不计划用于抽象-代码库中已经有它的实例,应该保持这种状态way@xetra11在这种情况下,
BackPack
不能扩展
Item
,也不能序列化。您可能需要按照Big_Foot1989的建议调整类层次结构。