swift - Swift 3 混合协议(protocol)、扩展和类继承的可能错误

标签 swift inheritance protocols swift3 protocol-extension

我正在学习所有关于 swift、OOP 和 POP 的知识。当我遇到一些意想不到的行为时,我一直在将它们混合在一起以创建一个抽象基类。它最好用代码来表达,我会展示它按预期工作,然后出乎意料(至少对我而言)。代码很长,但很简单。这里它工作正常:

protocol GodsWill           {          func conforms() }
extension GodsWill          {          func conforms() { print("Everything conforms to God's Will") } }
class TheUniverse: GodsWill {          func conforms() { print("The Universe conforms to God's Will") } }
class Life: TheUniverse     { override func conforms() { print("Life conforms to God's Will") } }
class Humans: Life          { override func conforms() { print("Though created by God, Humans think they know better") } }

let universe = TheUniverse()
let life = Life()
let humans = Humans()

universe.conforms()
life.conforms()
humans.conforms()
print("-------------------------")
let array:[GodsWill] = [universe,life,humans]
for item in array { item.conforms() }

这是输出:

The Universe conforms to God's Will
Life conforms to God's Will
Though created by God, Humans sometimes think they know better
-------------------------
The Universe conforms to God's Will
Life conforms to God's Will
Though created by God, Humans sometimes think they know better

这正是我所怀疑的。但是当第一个类没有 conforms() 的自定义实现时,我在我的应用程序中遇到了这个问题,如下所示:

protocol GodsWill           {          func conforms() }
extension GodsWill          {          func conforms() { print("Everything conforms to God's Will") } }
class TheUniverse: GodsWill {  }
class Life: TheUniverse     {          func conforms() { print("Life conforms to God's Will") } }
class Humans: Life          { override func conforms() { print("Though created by God, Humans sometimes think they know better") } }

let universe = TheUniverse()
let life = Life()
let humans = Humans()

universe.conforms()
life.conforms()
humans.conforms()
print("-------------------------")
let array:[GodsWill] = [universe,life,humans]
for item in array { item.conforms() }

请注意,TheUniverse 没有 conforms() 的自定义实现。这是输出:

Everything conforms to God's Will
Life conforms to God's Will
Though created by God, Humans sometimes think they know better
-------------------------
Everything conforms to God's Will
Everything conforms to God's Will
Everything conforms to God's Will

前三行 print() 正是我所期望和想要的,但后三行真的让我感到困惑。由于 conforms() 是一项协议(protocol)要求,因此它们应该与前三行相同。但是我得到的行为就好像 conforms() 是在协议(protocol)扩展中实现的,但没有列为协议(protocol)要求。 The Swift Programming Language 引用手册中没有关于此的内容。和 this WWDC video恰好在 30:40 证明了我的观点。

那么,我是不是做错了什么,误解了功能,还是我发现了 swift 3 中的错误?

最佳答案

经过进一步调查,我认为这与 WWDC 视频没有太大关系。

Universe 没有定义 conforms 方法,因此在 universe 上调用 conforms 将打印“Everything...”。

Life 定义了一个conforms 方法。然而,由于它继承自 universe,而 universe 由于扩展而已经具有 conforms 的实现,因此协议(protocol)并不真正需要 conforms 方法。因此,协议(protocol)类忽略了 Life 类中的 conforms 方法。也就是说,Life中的conforms方法是shadowing协议(protocol)扩展中的conforms方法,我们可以看到在输出中:

let a: TheUniverse = Life()
a.conforms()
Life().conforms()
// output:
// Everything conforms to God's Will
// Life conforms to God's Will

人类还有另一种符合的方法。这次,它是用 override 定义的。但是,此 override 不会覆盖协议(protocol)扩展中的 conforms 方法。相反,它覆盖了 Life 中的 conforms 方法,后者是 Humans 的直接父类(super class)。这可以通过以下代码的输出来证明:

let a: Life = Humans()
a.conforms()
// output:
// Though created by God, Humans sometimes think they know better

所以毕竟协议(protocol)扩展中的方法没有被覆盖。所以当你创建一些对象并将其放入[GodsWill]时,阴影不起作用,因此调用了协议(protocol)扩展方法。

关于swift - Swift 3 混合协议(protocol)、扩展和类继承的可能错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40200168/

相关文章:

ios - 连接丢失时显示 UIAlertView

ios - SKNode帧不正确?

python - 子类化 numpy.ndarray - 为什么 __array_finalize__ 在这里没有被调用两次?

java - 使用 Intent 在 Activity 之间传递自定义对象

swift - 无法更改对象的协议(protocol)一致性

windows - 用于打开资源管理器的自定义 URI 协议(protocol)

ios - 为什么我在检查发件人的类别时收到错误 "Cannot assign to the result of this expression"?

用于更快加载图像的 iOS Swift 技巧

Python:如何重用基本方法,同时允许方法内修改?

java - 在 Java 中扩展 Protocol Buffers