Swift:接受子类的协议

时间:2019-03-04 08:12:20

标签: swift protocols

我有一个协议:

protocol InspectableSource
{
    var headerView: NSView? { get }
    var footerView: NSView? { get }
    var mainContentViews: [NSView] { get }
}

然后我有一个采用此协议的类:

class MyClass: InspectableSource
{
    var mainContentViews: [MyNSViewSubclass]
}

MyClass的实例提供mainContentViews,其中充满了NSView子类的对象。斯威夫特对此wh之以鼻,不会编译...因为它是斯威夫特。

那么如何在协议中声明mainContentViews可以是NSView或其子类的任何类型的对象?

2 个答案:

答案 0 :(得分:1)

您可以使用关联的类型:

protocol InspectableSource
{
    associatedtype ViewType : NSView
    var headerView: ViewType? { get }
    var footerView: ViewType? { get }
    var mainContentViews: [ViewType] { get }
}

在符合条件的班级中:

class MyClass: InspectableSource
{
    typealias ViewType = MyNSViewSubclass
    var mainContentViews: [MyNSViewSubclass]
    // ...
}

但是请注意,这将阻止您将InspectableSource用作变量的类型。

如果您真的想将InspectableSource作为变量的类型。您可以尝试这种类型安全性较低的方法:

class MyClass: InspectableSource {
    Var mainContentViews: [MyNSViewSubclass]
    var inspectableMainContentViews: [NSView] {
        return mainContentViews 
    }
}

protocol InspectableSource {
    var inspectableMainContentView: [NSView] { get }
}

答案 1 :(得分:1)

如果您可以修改MyClass,建议您使用专用字段存储[MyNSViewSubclass],然后通过计算属性符合InspectableSource

protocol InspectableSource
{
    var mainContentViews: [NSView] { get }
}

class MyClass: InspectableSource
{
    var mainContentViews : [NSView]{
        return myNSViews
    }
    var myNSViews : [MyNSViewSubclass]

    init() {
        self.myNSViews = []
    }
}