需要从超类 属性 访问子类 属性

need to access subclass property from superclass property

我需要传递 decodable 类型的模型并从中访问标题和副标题,因为 Decodable 没有标题和副标题属性,所以我实现了 decodable 的扩展并向 Decodable 添加了标题和副标题属性所以任何 [= Decodable 类型的 20=] 可以写 decodableObject.title 所以当我传递符合 decodable 并包含标题和副标题属性的 object 时,我需要访问它的数据而不是 Docodable object 数据但是它只是访问 Decodable 扩展属性以便访问我的目标 object 会发生什么我应该向下转换到这个 class 然后我应该为每个模型类型编写实现

//decalring struct which conforms to Decodable 
struct TestModel:Decodable {
    var title:String?
}
//added property 
extension Decodable {
    var title:String?{
        return "Decodable base"
    }
}

func setup(){
        var testModel = TestModel()
        testModel.title = "Subclass"
        checkProperties(model: testModel, mod: TestModel.self)
    }

    func checkProperties<T:Decodable>(model:Any,mod:T.Type){
        typealias MMM = T
        let title = (model as! MMM).title
        print("type is \(title)")
    }
// the resutl will be "Type is Decodable Base"

我需要预期的结果 // 结果将是 "Type is subclass"

嗯,也许这对你有帮助:

protocol HasTitle {
  var title: String? { get }
}

extension Decodable {
  var title:String? {
    return "Decodable base"
  }
}

struct TestModel: Decodable, HasTitle {
  var title: String?
}

func checkProperties<T:HasTitle>(model:Any,mod:T.Type){
  typealias MMM = T
  let title = (model as! MMM).title
  print("type is \(title)")
}

编辑

这利用了一个称为追溯建模的概念。基本原理是在一个协议中将 属性 分开,我称之为 HasTitle。诀窍是对 Decodable 进行扩展,其中有一个 属性 title 声明的方式与您在 HasTitle 协议中期望的方式相同。然后,无论哪种类型符合 Decodable 默认情况下都会得到 title 属性,你只需要声明 HasTitle 一致性。但是,您仍然可以随意覆盖它 title 属性.