我知道这个问题的标题令人困惑,但下面的例子解释了奇怪的行为:
protocol Protocol {
func method() -> String
}
extension Protocol {
func method() -> String {
return "From Base"
}
}
class SuperClass: Protocol {
}
class SubClass: SuperClass {
func method() -> String {
return "From Class2"
}
}
let c1: Protocol = SuperClass()
c1.method() // "From Base"
let c2: Protocol = SubClass()
c2.method() // "From Base"
c1.method()
和c2.method()
如何归来?为什么SubClass中的method()
不起作用?
有趣的是,如果没有声明c2的类型,这将起作用:
let c2 = SubClass()
c2.method() // "From Class2"
答案 0 :(得分:1)
问题是c1
和c2
的类型为Protocol
,因为您已经以这种方式明确定义了它们的类型(请记住:协议是完全成熟的类型)。这意味着,在调用method()
时,Swift会调用Protocol.method
。
如果您定义如下内容:
let c3 = SuperClass()
... c3
的类型为SuperClass
。由于SuperClass
没有更具体的method()
声明,因此在调用Protocol.method()
时仍会使用c3.method()
。
如果您定义如下内容:
let c4 = SubClass()
... c4
的类型为SubClass
。由于SubClass
确实有更具体的method()
声明,因此在调用SubClass.method()
时会使用c4.method()
。
你也可以c2
来调用SubClass.method()
,将它下载到`SubClass:
(c2 as! SubClass).method() // returns "From Class2"
这是SwiftStub的演示。
答案 1 :(得分:0)
我不太确定底层机制,但它必须与协议不一定允许继承这一事实有关。
解决此问题的一种方法是将方法添加到SuperClass
import Foundation
protocol Protocol: class {
func method() -> String
}
extension Protocol {
func method() -> String {
return "From Base"
}
}
class SuperClass: Protocol {
func method() -> String {
return "From Super"
}
}
class SubClass: SuperClass {
override func method() -> String {
return "From Class2"
}
}
let c1: Protocol = SuperClass()
c1.method() // "From Super"
let c2: Protocol = SubClass()
c2.method() // "From Class2"
答案 2 :(得分:0)
基本上是的,如果有一个符合协议的超类但没有为它提供实现,那么协议扩展的实现将在子类中可用,即使子库已实现(但是它们必须被转换为超类或协议的类型。
但是,如果超类具有协议方法的实现,那么协议的实现将无法从超类或其子类中获得。