// Designated Intializer : 지정 생성자 (Initializer Delegate를 해야함)
// - default init을 사용하거나 슈퍼 클래스에서 designated Init을 상속한게 아니면 최소한 하나의 designated Init이 필요함
// - super 클래스의 designated init을 호출해야함
// Convenience Intializer : 간편 생성자
// - super 클래스의 designated init을 직접 호출할 수 없음
// - 반드시 동일한 클래스의 init을 호출해서 최종적으로 designated init이 호출되도록 해야 함
class Position {
var x: Double
var y: Double
// 모든 속성을 초기화 해야한다. -> Designated Init
init(x: Double, y: Double) {
self.x = x
self.y = y
}
// Convenience init -> 유틸적으로 사용함 (필요한 속성만 초기화 하고 클래스에 있는 다른 init을 호출해서 나머지 초기화를 진행한다.)
convenience init(x: Double) {
self.init(x: x, y: 0.0) // designated init 호출
}
}
Initializer Inheritance
// init 또한 서브 클래스로 상속된다.
// 근데 조금 까다롭다.
// 기본적으로 super class로 구현한 init은 subclass로 상속되지 앟는다.
// 1. 서브 클래스의 모든 속성이 기본값으로 초기화 되어 있고 designated init을 직접 구현하지 않았다면 super class의 모든 deisgnated init이 상속된다.
// 2. 서브 클래스가 모든 desiganted init을 상속받았거나 overriding 했다면 모든 convenience init이 상속된다.
class Figure {
var name: String
init(name: String) {
self.name = name
}
func draw() {
print("draw \(name)")
}
convenience init() {
self.init(name: "Unknown")
}
}
class Rectangle: Figure {
var width: Double = 0.0
var height: Double = 0.0
init(name: String, width: Double, height: Double) {
// 문제
// 1. 슈퍼클래스의 desiganted init을 호출하지 않고 있다.
// 2. 상위 구현을 호출하기 전에 상속받은 name 속성에 접근하고 있다.
// 보통은 현재 클래스에 정의된 속성만 init하고 나머지는 슈퍼 클래스에 맡긴다.
// self.name = name
// self.width = width
// self.height = height
// 문제해결
self.width = width
self.height = height
super.init(name: name)
}
override init(name: String) {
width = 0
height = 0
super.init(name: name)
}
// override를 하지 않았음에도 에러가 발생하지 않는다.
// convenience는 기본적으로 같은 클래스의 init을 호출한다.
// super class의 init을 호출하는 것은 기본적을 불가능 -> overriding이라는 개념이 적용되지 않는다.
convenience init() {
self.init(name: "Unknown")
}
}