【发布时间】:2016-08-17 23:53:20
【问题描述】:
考虑以下游乐场:
protocol A {
func f() -> String
}
extension A {
func f() -> String { return "AAAA" }
}
class B: A {}
class C: B {
func f() -> String { return "CCCC" }
}
let a: A = C()
let b: B = C()
let c: C = C()
a.f() // "AAAA" - why?
b.f() // "AAAA" - why?
c.f() // "CCCC"
我不明白为什么 a.f() 和 b.f() 返回 "AAAA" - 它们应该返回 "CCCC" 因为 func f() -> String 应该是动态调度的(正如它在协议中声明的那样)。
如果我将class B 更改为如下所示:
class B: A {
func f() -> String { return "BBBB" }
}
然后对.f() 的所有三个调用都按预期返回"CCCC"。
我觉得这是 Swift 编译器中的一个错误,我在 Xcode 7.3.1 和 8.0-beta3 中检查过,这种行为在两者中都可以重现。
这实际上是预期的行为吗?
【问题讨论】:
-
@matt,我不同意这个问题是重复的,因为基本协议将
f()方法声明为要求,而不是扩展,因此链接的问题没有回答我的问题。请考虑重新提出这个问题。 -
这是重复的,因为答案回答了您的问题。
-
也不要认为这是重复的。
-
虽然相似,但我也不认为这是重复的。拥有相同的答案不会使问题重复。例如。 “什么是2+1?”和“π的第一个数字是多少?”。不是重复的问题,相同的答案。
-
引用朋友的话,tldr 是:“只有声明一致性的类才能获得协议见证表”。出于这个原因,子类忽略了协议