생성자의 상속과 재정의 (기본 원칙)
상위 클래스의 생성자가 하위 클래스에서 상속되지 않는 이유
- 하위 클래스는 상위 클래스의 생성자를 기본적으로 상속하지 않는다
- 하위 클래스에 정의된 저장 속성이 초기화되지 않을 위험을 방지하기 위해서이다
- 하위 클래스는 자신의 저장 속성을 완전히 초기화하기 전에 상위 클래스의 초기화를 호출해야 한다 (
super.init())
상위 클래스의 생성자를 하위 클래스에서 사용하려면 재정의가 필요하다 (Override)
- 상위 클래스의 지정 생성자를 하위 클래스에서 동일한 이름으로 구현하려면
override 키워드를 사용해야 한다
- 상위 클래스의 지정 생성자를 하위 클래스에서 편의 생성자로 재정의하는 것도 가능하다 (
override convenience)
편의 생성자의 자동 상속 조건
- 하위 클래스에서 모든 저장 속성이 기본값으로 초기화되면, 상위 클래스의 지정 생성자가 자동으로 상속된다
- 하위 클래스에서 상위 클래스의 모든 지정 생성자를 재정의하면, 상위 클래스의 편의 생성자가 자동으로 상속된다
지정 생성자와 편의 생성자의 상속과 재정의 예제
class Appliance {
var brand: String
init(brand: String) {
self.brand = brand
}
convenience init() {
self.init(brand: "Unknown")
}
}
let appliance1 = Appliance()
let appliance2 = Appliance(brand: "Samsung")
print("Appliance1 Brand: \(appliance1.brand)")
print("Appliance2 Brand: \(appliance2.brand)")
class WashingMachine: Appliance {
var capacity: Int
override init(brand: String) {
self.capacity = 0
super.init(brand: brand)
}
init(brand: String, capacity: Int) {
self.capacity = capacity
super.init(brand: brand)
}
convenience init() {
self.init(brand: "LG", capacity: 8)
}
}
let washer1 = WashingMachine()
let washer2 = WashingMachine(brand: "Whirlpool")
let washer3 = WashingMachine(brand: "Bosch", capacity: 12)
print("Washer1: \(washer1.brand), Capacity: \(washer1.capacity)")
print("Washer2: \(washer2.brand), Capacity: \(washer2.capacity)")
print("Washer3: \(washer3.brand), Capacity: \(washer3.capacity)")
Apple 공식 문서의 예제
class Vehicle {
var numberOfWheels = 0
var description: String {
return "\(numberOfWheels) wheel(s)"
}
}
let vehicle = Vehicle()
print("Vehicle: \(vehicle.description)")
class Bicycle: Vehicle {
override init() {
super.init()
numberOfWheels = 2
}
}
let bicycle = Bicycle()
print("Bicycle: \(bicycle.description)")
class Hoverboard: Vehicle {
var color: String
init(color: String) {
self.color = color
super.init()
}
override var description: String {
return "\(super.description) in a beautiful \(color)"
}
}
let hoverboard = Hoverboard(color: "Silver")
print("Hoverboard: \(hoverboard.description)")
요약
- 지정 생성자는 모든 저장 속성을 초기화하고 상위 클래스의 지정 생성자를 호출해야 한다 (
super.init())
- 편의 생성자는 동일 클래스의 지정 생성자를 호출하여 초기화를 위임한다 (
self.init())
- 지정 생성자는 편의 생성자를 호출할 수 없다
- 편의 생성자는 상위 클래스의 지정 생성자를 직접 호출할 수 없다
- 지정 생성자를 재정의하려면
override 키워드를 사용해야 한다
- 하위 클래스에서 모든 저장 속성을 기본값으로 초기화하면, 상위 클래스의 지정 생성자가 자동으로 상속된다
- 상위 클래스의 모든 지정 생성자를 재정의하면, 상위 클래스의 편의 생성자가 자동으로 상속된다