解码子类时忽略超类 属性

Ignoring superclass property while decoding subclass

我正在尝试创建继承的数据模型以便用 JSONDecoder 解析它。

class FirstClass : Codable {
    let firstClassProperty: Int
    final let arrayOfInts: [Int]
}

class SecondClass : FirstClass {
    let secondClassProperty1: Int
    let secondClassProperty2: Int

    private enum CodingKeys : String, CodingKey {
        case secondClassProperty1, secondClassProperty2
    }

    required init(from decoder: Decoder) throws {
        let container = try decoder.container(keyedBy: CodingKeys.self)

        secondClassProperty1 = try container.decode(Int.self, forKey: .secondClassProperty1)
        secondClassProperty2 = try container.decode(Int.self, forKey: .secondClassProperty2)

        try super.init(from: decoder)
    }
}

我将此 JSON 用于 FirstClass:

{
    "firstClassProperty":  123,
    "arrayOfInts": [
        123
    ]
}

这是 SecondClass:

{
  "firstClassProperty": {},
  "secondClassProperty1": {},
  "secondClassProperty2": {}
}

如果关键字 final 在这种情况下不起作用,我如何摆脱子类中的 arrayOfInts 但让它在超类中?

这是Playground。感谢您的回答!

一个快速的技巧是将其声明为可选。例如:

class FirstClas: Codable {
    let firstClassProperty: Int
    final let arrayOfInts: [Int]?
}

这将自动解决缺失的 arrayOfInts

手动解决。另一个解决方案是自己实现 Decodable 协议——就像你在 SecondClass 中所做的那样——并使用 decodeIfPresent 解码 arrayOfInts(否则使用默认值)。


超类解码。顺便说一下,将 Decoder 转发到超类的推荐方法是使用 superDecoder() 方法:

...
let superDecoder = try container.superDecoder()
try super.init(from: superDecoder)

你可以这样使用:

class FirstClass : Codable {
    let firstClassProperty: Int
    final let arrayOfInts: [Int]?
    required init(from decoder: Decoder) throws {
        let container = try decoder.container(keyedBy: CodingKeys.self)
        firstClassProperty = try container.decode(Int.self, forKey: .firstClassProperty)
        arrayOfInts = try container.decodeIfPresent([Int].self, forKey: .arrayOfInts)
    }
}