Swift: 接受子类的协议

Swift: Protocol That Accepts Subclasses

我有一个协议:

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

那我有一个class采用了这个协议:

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

MyClass 的实例提供 mainContentViews,其中充满了 NSView 的子class对象。 Swift 抱怨这个并且不会编译...因为它是 Swift.

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

您可以使用关联类型:

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

并且在你的符合 class:

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 }
}

如果你可以修改MyClass,我建议使用专用字段来存储你的[MyNSViewSubclass],然后通过计算属性.[=14=来符合InspectableSource ]

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

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

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