我正在学习所有关于 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/