You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将Kotlin中的food类改为sealed class并正确实例化?

Kotlin密封类改造及Jackson注解适配方案

问题描述

我是Kotlin新手,现有一个带Jackson注解的open food类,关联foodType枚举类,想把它改造成密封类(或作为密封类的子类),但不知道怎么正确传递参数实例化。参考了一些帖子写了部分代码,但对参数传递很困惑,请求帮助。

原代码

原food类

@JsonTypeInfo(
    use = JsonTypeInfo.Id.NAME,
    include = JsonTypeInfo.As.PROPERTY,
    property = "type")
@JsonSubTypes(
    JsonSubTypes.Type(value = A::class, name = "PIZZA"),
    JsonSubTypes.Type(value = B::class, name = "DONUT"),
    JsonSubTypes.Type(value = C::class, name = "ICECREAM"),
    JsonSubTypes.Type(value = D::class, name = "CHOCOLATE"),
)
open class food (var type: foodType, var quantity : String) {
    open val taste : String=""
}

foodType枚举类

enum class foodType {
    PIZZA,
    DONUT,
    ICECREAM,
    CHOCOLATE
}

尝试的代码

sealed class food (var type: foodType, var quantity: String) {
    class favFood(taste: String): food(?, ?)
}

解决方案

核心思路是让密封类的每个子类对应固定的FoodType枚举值,这样实例化子类时无需手动传递type参数,同时保留Jackson注解保证序列化反序列化正常工作。

改造后的完整代码

// 规范命名:类名首字母大写
enum class FoodType {
    PIZZA,
    DONUT,
    ICECREAM,
    CHOCOLATE
}

@JsonTypeInfo(
    use = JsonTypeInfo.Id.NAME,
    include = JsonTypeInfo.As.PROPERTY,
    property = "type"
)
@JsonSubTypes(
    JsonSubTypes.Type(value = Food.PizzaFood::class, name = "PIZZA"),
    JsonSubTypes.Type(value = Food.DonutFood::class, name = "DONUT"),
    JsonSubTypes.Type(value = Food.IceCreamFood::class, name = "ICECREAM"),
    JsonSubTypes.Type(value = Food.ChocolateFood::class, name = "CHOCOLATE"),
)
sealed class Food(val type: FoodType, var quantity: String) {
    // 将taste改为抽象属性,强制子类实现,避免空默认值的冗余
    abstract val taste: String

    // 每个子类对应一个固定的FoodType,实例化时仅需传递quantity和taste
    class PizzaFood(quantity: String, override val taste: String) : Food(FoodType.PIZZA, quantity)
    class DonutFood(quantity: String, override val taste: String) : Food(FoodType.DONUT, quantity)
    class IceCreamFood(quantity: String, override val taste: String) : Food(FoodType.ICECREAM, quantity)
    class ChocolateFood(quantity: String, override val taste: String) : Food(FoodType.CHOCOLATE, quantity)
}

关键说明

  1. 参数传递逻辑:每个子类在继承密封类时,直接传入对应的FoodType枚举值,外部实例化子类时只需要传递quantity和taste,无需关心type参数。
  2. Jackson注解适配:保留原有的@JsonTypeInfo和@JsonSubTypes注解,仅修改@JsonSubTypes.Type的value为对应的子类类引用,确保序列化反序列化时能正确识别类型。
  3. 代码规范优化:类名和枚举类名首字母大写,将父类的taste改为abstract val,强制子类提供具体值,比原有的open val更严谨。

实例化示例

// 实例化披萨,自动关联FoodType.PIZZA
val cheesePizza = Food.PizzaFood(quantity = "2 slices", taste = "浓郁芝士味")
// 实例化甜甜圈,自动关联FoodType.DONUT
val glazedDonut = Food.DonutFood(quantity = "1个", taste = "甜腻糖霜味")

内容的提问来源于stack exchange,提问作者Kate

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.19 13:25:38