swift - 您是否需要从每个子类的函数中调用超类的实现
问题描述
例如,您定义了一个覆盖其超类中的函数 f 的子类。在覆盖内部,您是否需要调用超类的 f 函数。
解决方案
默认情况下,您调用super
,除非您知道您没有破坏该功能。
我创建了一个要点。您可以将其复制到您自己的游乐场并玩弄它。但答案是:
我对你有这种确切的困惑。您基本上是在问扩展行为与覆盖行为之间有什么区别。
斯威夫特并没有很好地告诉你他们的区别。他们的共同点是都需要用 来标记函数override
,但有时除了超类的实现(扩展)之外,您还在做一些事情,有时您只是完全重写它(覆盖)
假设我们有以下类:
class Person {
var age : Int?
func incrementAge() {
guard age != nil else {
age = 1
return
}
age! += 1
}
func eat() {
print("eat popcorn")
}
}
我们可以初始化它并执行以下操作:
var p1 = Person()
p1.incrementAge() // works fine
现在假设我们这样做了:
class Boy : Person{
override func incrementAge() {
age! += 2
}
}
var b1 = Boy()
b1.incrementAge()
你觉得会发生什么?!
它会崩溃。因为在超类中,我们正在nil
检查age
,但在我们的子类中我们从不调用super
为了使它工作,我们必须调用super
.
class GoodBoy : Person{
override func incrementAge() {
super.incrementAge()
age! += 2
}
}
var b2 = GoodBoy()
b2.incrementAge() // works fine.
我们可以不直接打电话就离开super
。
class AlternateGoodBoy : Person{
override func incrementAge() {
guard age != nil else {
age = 1
return
}
age! += 2
}
}
var b3 = AlternateGoodBoy()
b3.incrementAge() // works fine.
^^ 以上工作,但我们并不总是知道超类的实现。一个真实的例子是UIKit
。我们不知道当viewDidLoad
被调用时会发生什么。因此我们必须调用super.viewDidLoad
话虽如此,有时我们不能打电话super
并完全没问题,因为我们知道 super 做什么,或者可能只是不关心并想要完全摆脱它。例如:
class Girl : Person{
override func eat() {
print("eat hotdog")
}
}
var g1 = Girl()
g1.eat() // doesn't crash, even though you overrode the behavior. It doesn't crash because the call to super ISN'T critical
然而,最常见的情况是您调用super
,但还要在其上添加一些内容。
class Dad : Person {
var moneyInBank = 0
override func incrementAge() {
super.incrementAge()
addMoneyToRetirementFunds()
}
func addMoneyToRetirementFunds() {
moneyInBank += 2000
}
}
var d1 = Dad()
d1.incrementAge()
print(d1.moneyInBank) // 2000
专家提示:
与大多数先调用super
然后调用其余部分的覆盖不同,对于tearDown
函数,最好super.tearDown()
在函数末尾调用。通常,对于任何“删除”功能,您都希望在最后调用 super。例如viewWillDisAppear
/viewDidDisappear
推荐阅读
- java - 计算我的用户节点中称为“数量”的所有子值的总和
- java - 调整浏览器窗口大小后无法从元素中获取文本(Chrome)
- cmake - 在 CMake 中捕获请求的并行作业
- javascript - 用于制作多个类组件的 React 函数
- powerbi - 添加列时如何重新使用 CALCULATE 函数中使用的过滤器
- r - 通过列表创建循环并将输出添加到数据框
- c - 从二维数组打印一个字符
- tsql - 如何在行号之间添加破折号,在非行号之间添加逗号
- java - Facing Some problem with Firebase InstanceId
- javascript - Redux - Saga,放置父函数