我正在学习关于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()是协议要求,因此它们应与前三行相同。但我得到的行为好像在协议扩展中实现了conforms(),但未列为协议要求。 “Swift编程语言”参考手册中没有任何相关内容。而this WWDC video恰好在30:40证明了我的观点。
那么,我做错了什么,误解了功能,还是我在swift 3中发现了一个错误?
答案 0 :(得分:1)
经过进一步调查,我认为这与WWDC视频无关。
Universe没有定义conforms
方法,因此在Universe上调用conforms
将打印“Everything ...”。
Life定义了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
方法,Humans
是let a: Life = Humans()
a.conforms()
// output:
// Though created by God, Humans sometimes think they know better
的直接超类。这可以通过以下代码的输出来证明:
Integer.parse()
毕竟,协议扩展中的方法不会被覆盖。因此,当您创建一些对象并将其放入[GodsWill]时,阴影无效,因此调用协议扩展方法。