可编码类的继承

时间:2018-01-13 08:28:06

标签: inheritance swift4 codable decodable encodable

我正在使用Swift 4和Xcode 9.2编写程序。我在编写可编码类(完全是类,而不是struct)时遇到了困难。当我尝试从另一个类继承一个类时,JSONEncoder不从子类(子)获取所有属性。请看这个:

class BasicData: Encodable {

    let a: String
    let b: String

    init() {
        a = "a"
        b = "b"
    }
}

class AdditionalData: BasicData {

    let c: String

    init(c: String) {
        self.c = c
    }

}

let encode = AdditionalData(c: "c")

do {
    let data = try JSONEncoder().encode(encode)
    let string = String(data: data, encoding: .utf8)
    if let string = string {
        print(string)
    }
} catch {
}

它会打印出来:{"a":"a","b":"b"}

但我需要这个:{"a":"a","b":"b","c":"c"}

看起来类c的{​​{1}}属性只是在某处丢失了。

所以问题是:如果我有使用协议编码的类Encodable如何正确地创建子类(这个类的子类,继承)类?

我将感谢任何帮助或建议。

2 个答案:

答案 0 :(得分:10)

public Chunk GetChunkByWorldPos(Vector3 pos) { Vector3 chunkPos = new Vector3((int)(pos.x / World.staticChunkSize), (int)(pos.y / World.staticChunkSize), (int)(pos.z / World.staticChunkSize)); return GetChunkByPos(chunkPos); } Encodable涉及一些代码综合,其中编译器基本上为您编写代码。当您将Decodable符合BasicData时,这些方法将写入Encodable类,因此它们不知道子类定义的任何其他属性。您必须覆盖子类中的BasicData方法:

encode(to:)

有关class AdditionalData: BasicData { let c: String let d: Int init(c: String, d: Int) { self.c = c self.d = d } private enum CodingKeys: String, CodingKey { case c, d } override func encode(to encoder: Encoder) throws { try super.encode(to: encoder) var container = encoder.container(keyedBy: CodingKeys.self) try container.encode(self.c, forKey: .c) try container.encode(self.d, forKey: .d) } } 的类似问题,请参阅this question

答案 1 :(得分:0)

在我的情况下,基类不必真的是可编码的。只有子类需要是可编码的。在这种情况下,不要将基类声明为Codable,而要声明子类。这样,您无需执行任何此类encoding / codingKeys / init(来自:Decoder)样板工作。希望这对某些人有帮助。