问题
I am writing a program using Swift 4 and Xcode 9.2. I have faced difficulties with writing encodable class (exactly class, not struct). When I am trying to inherit one class from another, JSONEncoder does not take all properties from sub class (child). Please look at this:
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 {
}
It will print this: {"a":"a","b":"b"}
But I need this: {"a":"a","b":"b","c":"c"}
It look like c
property of class AdditionalData
just lost somewhere and somehow.
So question is: if I have class signed with protocol Encodable how to make sub class (child of this class, inherit) class properly?
I will be thankful for any help or advice.
回答1:
Encodable
and Decodable
involve some code synthesis where the compiler essentially writes the code for you. When you conform BasicData
to Encodable
, these methods are written to the BasicData
class and hence they are not aware of any additional properties defined by subclasses. You have to override the encode(to:)
method in your subclass:
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)
}
}
See this question for a similar problem with Decodable
.
来源:https://stackoverflow.com/questions/48238196/inheritance-of-encodable-class