Inheritance and class initialization
The previous chapter briefly introduced you to class initializers, which are similar to their struct counterparts. With subclasses, there are a few more considerations with regard to how you set up instances.
Let’s introduce a modification to the StudentAthlete class that adds a list of sports an athlete plays:
class StudentAthlete: Student { var sports: [String]
//…
}
Because sports doesn’t have an initial value, StudentAthlete must provide one in its own initializer:
class StudentAthlete: Student { var sports: [String]
init(sports: [String]) { self.sports = sports
// Build error - super.init isn’t called before
// returning from initializer
}
//…
}
Uh-oh! The compiler complains that you didn’t call super.init by the end of the initializer:
Initializers require calling super.init because without it, the superclass won’t be able to provide initial states for all its stored properties — in this case, firstName and lastName. Let’s make the compiler happy:
class StudentAthlete: Student { var sports: [String]
init(firstName: String, lastName: String, sports: [String]) { self.sports = sports
super.init(firstName: firstName, lastName: lastName)
}
//…
}
The initializer now calls the initializer of its superclass, and the build error is gone. Notice that the initializer now takes in a firstName and a lastName to satisfy the requirements for calling the Person initializer.
You also call super.init after you initialize the sports property, which is an enforced rule.