【问题标题】:Swift: override property classSwift:覆盖属性类
【发布时间】:2018-06-29 16:53:26
【问题描述】:

借助 Swift 协议、扩展和约束,我希望做两件事:

  1. 创建一个基本抽象类
  2. 子类和覆盖属性。

    class PropertyBase { }
    
    class PropA : PropertyBase {}
    
    class PropB : PropertyBase {}
    
    class ControllerBase {
        var prop: PropertyBase?
    }
    
    class ControllerA : ControllerBase{
        override var prop: PropA?
    }
    class ControllerB : ControllerBase{
        override var prop: PropB?
    }
    

错误:

无法覆盖“PropertyBase”类型的可变属性“prop”?具有协变类型 'PropA?

很高兴知道我如何用不同的方法实现这一目标?

编辑

我想更清楚地说明我想要实现的目标。

在示例中,我正在构建一个处理未知对象类型的协议,我只知道该类型可能是 String 或 Int 或完全不同的类 Resource。我想通过添加扩展来支持这些不同的类型类。至少那是我认为正确的方法,但是

public protocol InstrumentProtocol : class  {
    associatedtype Item: AnyObject
    var item: Item? { get set }
    var identifier: String? { get }
}
public class AbstractBase : InstrumentProtocol {

    public var item: AnyObject?
    public var identifier: String?
    public init(_ i : AnyObject) {
        item = i
    }
    public func about() {
        print(self.item) // Any Object
    }
}

//// This is what I want to achieve, but it doesn't work
public extension InstrumentProtocol where Self.Item : Instrument {

    public func about() {
        print(self.item) //Should be of Instrument type
    }
}

 public extension InstrumentProtocol where Self.Item : String {

    public func about() {
        print(self.item) //Should be of String type
    }
}

item 属性类型我不知道。在这种情况下,这将是最好的方法吗?

【问题讨论】:

    标签: swift generics swift4 swift-protocols


    【解决方案1】:

    你可以这样做:

    class PropertyBase { }
    class PropA : PropertyBase {}
    class PropB : PropertyBase {}
    
    protocol ControllerBaseType {
      associatedtype T: PropertyBase    
      var prop : T? { get set }
    }
    
    class ControllerA : ControllerBaseType {
      var prop: PropA?
    }
    class ControllerB : ControllerBaseType {
      var prop: PropB?
    }
    

    ControllerBaseType 是您想要的抽象,并且您在每个子类中都有prop 的具体实现

    编辑: 根据@Honey 的评论,我通过从子类中删除类型别名来简化代码

    EDIT2: 如果你真的需要 ControllerBase 作为一个班级,你可以这样做:

    class ControllerBase<T: PropertyBase> {
      var prop : T?
    }
    
    class PropertyBase { }
    class PropA : PropertyBase {}
    class PropB : PropertyBase {}
    
    class ControllerA : ControllerBase<PropA> {}
    class ControllerB : ControllerBase<PropB> {}
    

    【讨论】:

    • FWIW 你也可以隐式地遵守。即删除` typealias T = PropA` & 行。因为var prop: PropA? 足以让编译器推断。 ControllerB 也一样...
    • 感谢您的回答,我想要 ControllerBase Class 而不是协议的原因是因为我可以将它用作另一个类中的 ivar。 class New { var controller : ControllerBase? },在这里我可以隐式使用任何 Controller 类。我很困惑。
    • 嗯,如果我理解正确的话,您可以使用protocol 来做到这一点。在您尝试创建 ControllerBaseType 的实例之前一切正常,但您可以拥有 ControllerBaseType 类型的变量
    • @user134611 请检查 EDIT2
    • *一切正常,直到您 don't 尝试创建 ControllerBaseType 的实例...
    猜你喜欢
    • 2016-07-13
    • 2018-06-09
    • 1970-01-01
    • 2013-04-05
    • 2014-12-28
    • 1970-01-01
    • 2016-06-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多