exi*_*all 37 inheritance protocols interface typechecking swift
我正在创建几个NSView类,所有类都支持特殊操作,我们将调用它们transmogrify.乍一看,这似乎是协议的完美之处:
protocol TransmogrifiableView {
func transmogrify()
}
Run Code Online (Sandbox Code Playgroud)
然而,该协议并没有执行,每一个TransmogrifiableView是一个NSView为好.这意味着NSView我在a上调用的任何方法TransmogrifiableView都不会键入check:
let myView: TransmogrifiableView = getTransmogrifiableView()
let theSuperView = myView.superView // error: TransmogrifiableView does not have a property called 'superview'
Run Code Online (Sandbox Code Playgroud)
我不知道如何要求实现我的协议的所有类也是子类NSView.我试过这个:
protocol TransmogrifiableView: NSView {
func transmogrify()
}
Run Code Online (Sandbox Code Playgroud)
但是Swift抱怨协议不能从类继承.将协议转换为仅使用类的协议没有帮助
protocol TransmogrifiableView: class, NSView {
func transmogrify()
}
Run Code Online (Sandbox Code Playgroud)
我不能创建TransmogrifiableView超类而不是协议,因为我的一些TransmogrifiableView类必须是其他非transmogrifiable视图的子类.
我应该如何要求所有TransmogrifiableView的也可以NSView的?我真的不想用as"转换"来改变我的代码,这种转换形式不好而且分散注意力.
Cri*_*tik 17
通过使用关联类型来强制执行子类,有一种解决方法:
protocol TransmogrifiableView {
associatedtype View: NSView = Self
func transmogrify()
}
class MyView: NSView, TransmogrifiableView { ... } // compiles
class MyOtherClass: TransmogrifiableView { ... } // doesn't compile
Run Code Online (Sandbox Code Playgroud)
Ant*_*ine 17
从Swift 4开始,您现在可以将其定义如下:
let myView: NSView & TransmogrifiableView
Run Code Online (Sandbox Code Playgroud)
有关更多信息,请查看问题#156 Subclass Existentials
Gra*_*lix 10
你可以使用这样的东西:
protocol TransmogrifiableView where Self:NSView {}
Run Code Online (Sandbox Code Playgroud)
这要求所有创建的实例符合TransmogrifiableView协议,并使用NSView进行子类化
我认为您是的子类NSView。尝试这个:
protocol TransmogrifiableView {
func transmogrify()
}
class MyNSView: NSView, TransmogrifiableView {
// do stuff.
}
Run Code Online (Sandbox Code Playgroud)
然后在代码中接受type的对象MyNSView。
您可能想要一个Extension,看到这个
extension NSView: TransmogrifiableView {
// implementation of protocol requirements goes here
}
Run Code Online (Sandbox Code Playgroud)
另一个选择是创建一个类,该类持有指向NSView的指针,并实现其他方法。这也将迫使您代理要使用的NSView中的所有方法。
class NSViewWrapper: TransmogrifiableView {
var view : NSView!
// init with the view required.
// implementation of protocol requirements goes here.
.....
// proxy all methods from NSView.
func getSuperView(){
return self.view.superView
}
}
Run Code Online (Sandbox Code Playgroud)
这很长而且不好,但是可以使用。我建议您仅在您确实无法使用扩展功能时才使用它(因为您需要使用NSViews而不需要额外的方法)。