Reputation: 11
e.g. you have a subclass defined which overrides a function f in its superclass. Inside the override, are you required to call the superclass's f function.
Upvotes: 0
Views: 707
Reputation: 36287
The default is that you call super
, unless you know you're not breaking that function.
I've created a gist. You can copy it to your own playground and play around with it. But the answer is:
I had this exact confusion of yours. You're basically asking what's the difference between extending behavior vs. overriding behavior.
Swift doesn't do a good a job of telling your their difference.
What they both share is that both need to mark the function with override
, but sometimes you're doing something in addition to the superclass's implementation (extending), and sometimes you're just completely rewriting it (overriding)
Suppose we have the following class:
class Person {
var age : Int?
func incrementAge() {
guard age != nil else {
age = 1
return
}
age! += 1
}
func eat() {
print("eat popcorn")
}
}
We can just initialize it and do:
var p1 = Person()
p1.incrementAge() // works fine
Now suppose we did this:
class Boy : Person{
override func incrementAge() {
age! += 2
}
}
var b1 = Boy()
b1.incrementAge()
What do you think is going to happen?!
It will crash. Because in the super class, we're doing a nil
check for age
, but in our subclass we never call super
To make it work we have to call super
.
class GoodBoy : Person{
override func incrementAge() {
super.incrementAge()
age! += 2
}
}
var b2 = GoodBoy()
b2.incrementAge() // works fine.
We could get away without calling super
directly.
class AlternateGoodBoy : Person{
override func incrementAge() {
guard age != nil else {
age = 1
return
}
age! += 2
}
}
var b3 = AlternateGoodBoy()
b3.incrementAge() // works fine.
^^ The above works, yet the superclass's implementation is not always known to us. A real example is UIKit
. We don't know what happens really when viewDidLoad
is called. Hence we must call super.viewDidLoad
That being said sometimes we could just not call super
and be totally fine because we know what super does or maybe just don't care and want to completely get rid of it. e.g. :
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
Yet the most common case is that you call super
, but also add something on top of it.
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:
Unlike most overrides where you first call super
then the rest, for a tearDown
function, it’s best to call super.tearDown()
at the end of the function. In general, for any 'removal' functions, you'd want to call super at the end. e.g. viewWillDisAppear
/viewDidDisappear
Upvotes: 1
Reputation: 12375
The answer is false, you don't need to call the superclass method you are overriding in Swift or in OOP in general. That would be a horrible limitation if you did! There are times when you should in fact not call it and perhaps the most common example is when you create a UIViewController
programmatically and have to override loadView()
without calling super.loadView()
.
Upvotes: 1
Reputation: 130102
The answer to this question is not really related to Swift but it's related to all OOP languages.
The simple answer is: No, you are not required to call the superclass implementation.
Whether you should call the superclass implementation or not should be stated in the documentation. When you are not sure, you should generally always call the super implementation.
You have to consider the fact that the superclass does something inside the method and if you don't call the superclass implementation, the subclass doesn't have to work properly.
Not calling the superclass implementation means that you want to prevent the superclass implementation from happening and that usually means your whole inheritance model is flawed.
One notable exception is the situation when the superclass provides some default implementation which you want to replace inside your subclass (e.g. UIViewController.loadView
). That's not a very common use case though.
There are also other obvious exceptions, for example getters. When you are overriding a getter to return a custom object, there is usually no need to call super
. However, again, even getters can technically initialize some structures in the superclass and it might be needed to call super.
Upvotes: 1