我正在创建几个 NSView
类,所有这些类都支持特殊操作,我们称之为 transmogrify
. 乍一看,这似乎是协议的完美之处:
protocol TransmogrifiableView {
func transmogrify()
}
但是,此协议并未强制每个 TransmogrifiableView
也是 NSView
. 这意味着我在 TransmogrifiableView
上调用的任何 NSView
方法都不会键入check:
let myView: TransmogrifiableView = getTransmogrifiableView()
let theSuperView = myView.superView // error: TransmogrifiableView does not have a property called 'superview'
我不知道如何要求所有实现我的协议的类也是 NSView
的子类 . 我试过这个:
protocol TransmogrifiableView: NSView {
func transmogrify()
}
但是Swift抱怨协议不能从类继承 . 将协议转换为仅使用类的协议没有帮助
protocol TransmogrifiableView: class, NSView {
func transmogrify()
}
I cannot make TransmogrifiableView a superclass rather than a protocol, because some of my TransmogrifiableView classes must be subclasses of other, non-transmogrifiable views.
我应该如何要求所有 TransmogrifiableView
也要 NSView
's? I really don'想要用“ as
”转换来加密我的代码,这些转换形式不好而且分散注意力 .
8 回答
对于Swift 4,基于@Antoine敏锐的洞察力:
创建协议然后使用typealias为符合类和协议的类型提供更清晰的名称 .
然后,您可以定义从该类型继承的类....
....或者定义一个继承自协议和子类的类
现在你可以做到这一点 .
这现在编译 .
仍然不是理想的解决方案,但这是我偶尔使用的模式:
使用要强制执行的方法定义协议 .
定义您的基类,实现您希望孩子们免费获得的任何内容 .
在该基类(来自#2)中,有一个在#1中创建的协议的可选"delegate"变量 .
定义所有子类,以便它们继承基类并实现协议 .
这让你的基类调用协议方法,同时强制孩子们实现它们(例如,self.myDelegate?.myProtocolMethod) .
根据定义,协议只声明了“方法,属性和其他要求”的要求,这意味着超类不是它的一部分 .
现在,我没有't see a clean solution. It'可以使用
where
-clause定义一个类型NSView
并且符合TransmogrifiableView
,如下所示:或者你可以使用另一个超类:
最后,这两种解决方案都不能让我满意 . 也许有一天会将
abstract
-keyword添加到Swift?在这里检查这个解决方案... Swift - class method which must be overridden by subclass
此解决方案允许从类继承并且还可以检查协议的编译时间 . :)
从Swift 4开始,您现在可以将其定义如下:
有关更多信息,请结帐#156 Subclass Existentials
你可以使用这样的东西:
这要求所有创建的实例符合TransmogrifiableView协议,并使用NSView进行子类化
我想你是在
NSView
的子类之后 . 试试这个:稍后在代码中接受
MyNSView
类型的对象 .编辑
你可能想要一个
Extension
,见this请注意,如果没有这种额外的方法,您将无法获得NSView .
您可以单独扩展NSView的子类以覆盖此新方法 .
另一种选择是创建一个包含指向NSView的指针的类,并实现其他方法 . 这也将强制您从NSView中代理要使用的 all 方法 .
这很长很不好,但会起作用 . 我建议你只在你真的无法使用扩展时才使用它(因为你需要NSView而不需要额外的方法) .
通过使用关联类型来强制执行子类,有一种解决方法: