这是我的继承结构
协议
protocol BaseProtocol {
}
protocol ChildProtocol: BaseProtocol {
}
类
class BaseClass: NSObject {
var myVar: BaseProtocol!
}
class ChildClass: BaseClass {
override var myVar: ChildProtocol!
}
我收到编译错误:
Property 'myVar' with type 'ChildProtocol!' cannot override a property with type 'BaseProtocol!'
实现这一目标的最佳方法是什么?
更新
我更新了尝试使用泛型实现解决方案的问题,但它不起作用:(这是我的代码(现在是真正的代码,没有示例)
协议
protocol TPLPileInteractorOutput {
}
protocol TPLAddInteractorOutput: TPLPileInteractorOutput {
func errorReceived(error: String)
}
类
class TPLPileInteractor<T: TPLPileInteractorOutput>: NSObject, TPLPileInteractorInput {
var output: T!
}
我的孩子们
class TPLAddInteractor<T: TPLAddInteractorOutput>: TPLPileInteractor<TPLPileInteractorOutput>, TPLAddInteractorInput {
}
好吧,在TPLAddInteractor
我无法访问self.output
内部,它会抛出编译错误,例如
'TPLPileInteractorOutput' does not have a member named 'errorReceived'
除此之外,当我创建TPLAddInteractor
let addInteractor: TPLAddInteractor<TPLAddInteractorOutput> = TPLAddInteractor()
我收到了其他错误
Generic parameter 'T' cannot be bound to non-@objc protocol type 'TPLAddInteractorOutput'
有什么想法吗?
答案 0 :(得分:1)
我认为你不能用protocols
来做到这一点我将解决您遇到的问题的方法是使用generics。这意味着您基本上拥有这样的类(更新为工作示例)。
<强>协议强>
protocol BaseProtocol {
func didSomething()
}
protocol ChildProtocol: BaseProtocol {
func didSomethingElse()
}
<强>类强>
class BaseClass<T: BaseProtocol> {
var myProtocol: T?
func doCallBack() {
myProtocol?.didSomething()
}
}
class ChildClass<T: ChildProtocol> : BaseClass<T> {
override func doCallBack() {
super.doCallBack()
myProtocol?.didSomethingElse()
}
}
实施/使用示例
class DoesSomethingClass : ChildProtocol {
func doSomething() {
var s = ChildClass<DoesSomethingClass>()
s.myProtocol = self
s.doCallBack()
}
func didSomething() {
println("doSomething()")
}
func didSomethingElse() {
println("doSomethingElse()")
}
}
let foo = DoesSomethingClass()
foo.doSomething()
请记住,您需要一个实际实现协议的类,以及您实际定义为BaseClass / ChildClass的泛型类的THAT类。由于代码期望类型是符合协议的类型。
答案 1 :(得分:1)
@tskulbru是正确的:它无法完成,这与您的协议无关。考虑下面的示例,其中也失败......这次是Cannot override with a stored property 'myVar'
:
class Foo {
}
class Goo: Foo {
}
class BaseClass: NSObject {
var myVar: Foo!
}
class ChildClass: BaseClass {
override var myVar: Foo!
}
要理解原因,让我们重新检查docs:
覆盖属性
您可以覆盖要提供的继承实例或类属性 您自己的该属性的自定义getter和setter,或者要添加 属性观察者使覆盖属性能够观察何时 基础财产价值变动。
暗示如果要覆盖属性,必须编写自己的getter / setter,否则必须添加属性观察者。不允许简单地将一种变量类型替换为另一种变量类型。
现在有一些猖獗的猜测:为什么会这样?好吧,一方面考虑Swift 打算为速度进行优化。必须进行运行时类型检查才能确定您的var实际上是Foo还是Bar,这会减慢速度。然后考虑语言设计者可能更喜欢组合而不是继承。如果这两个都是真的,那么你不能覆盖属性的类型就不足为奇了。
所有这一切,如果您需要获得相同的行为,@ tskulbru的解决方案看起来非常优雅,假设您可以进行编译。 :)
答案 2 :(得分:0)
您可以通过两种方式使用代码,具体取决于您希望使用代码实现的目标(您没有告诉我们)。
简单的情况:您只是希望能够将一个确认ChildProtocol的对象分配给myVar。 解决方案:不要覆盖myVar。只需在ChildClass中使用它。你可以通过设计Swift语言来做到这一点。它是面向对象语言的基础之一。
第二种情况:您不仅要启用分配ChildProtocol的实例,还要禁用能够分配BaseProtocol的实例。 如果您想这样做,请使用答案部分提供的Generics解决方案。
如果您不确定,这个简单的案例对您来说是正确的。
格尔德