我正在学习斯威夫特,哎呀,还有流行音乐。当我遇到一些意想不到的行为时,我一直把它们混合在一起构成一个抽象的基类。最好用代码来表示,我将展示它按预期工作,然后是出乎意料的(至少对我来说)。代码很长,但很简单。在这里它工作正常:

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() }

注意这里的universe没有定制的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()是协议要求,所以它们应该与前三行相同。但我得到的行为好像conforms()是在协议扩展中实现的,但没有列为协议要求。在Swift编程语言参考手册中没有任何相关内容。正好在30:40的时候证明了我的观点。
那么,我是做错了什么,误解了功能,还是在swift 3中发现了一个bug?

最佳答案

经进一步调查,我认为这与WWDC的视频没有太大关系。
宇宙并没有定义conforms方法,因此在宇宙上调用conforms将打印“一切…”。
生活定义了一种conforms方法。但是,由于它继承自universe,因为扩展已经实现了conforms,所以协议实际上并不需要conforms方法。因此,协议忽略了conforms类中的Life方法。换言之,conforms中的Life方法正在隐藏协议扩展中的conforms方法,如我们在输出中看到的:

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

人类有另一种方法。这一次,它是用conforms定义的。但是,这个override不会覆盖协议扩展中的override方法。相反,它重写了conforms中的conforms方法,后者是Life的直接超类。下面代码的输出可以证明这一点:
let a: Life = Humans()
a.conforms()
// output:
// Though created by God, Humans sometimes think they know better

因此,毕竟协议扩展中的方法不会被重写。因此,当您创建一些对象并将其放入[GodsWill]时,阴影没有效果,因此调用协议扩展方法。

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

10-08 23:41