По умолчанию вы вызываете 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
и быть в полном порядке, потому что мы знаем, что делает супер или, возможно, просто не заботимся и хотим полностью получитьИзбавься от этого.Например:
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
Pro tip:
В отличие от большинства переопределений, когда вы сначала вызываете super
, а затем остальные, для функции tearDown
лучшедля вызова super.tearDown()
в конце функции.В общем, для любых «удаленных» функций вы должны вызывать super в конце.например, viewWillDisAppear
/ viewDidDisappear