Notice
Recent Posts
Recent Comments
Link
大器晩成
클래스의 지정, 편의 생성자의 상속과 재정의 본문
생성자 상속 시 구현 규칙
- 상위의 지정생성자(이름/파라미터)와 현재단계의 저장속성을 고려해서 구현합니다.
[1단계 - 상위 생성자에 대한 고려]
- 상위에 어떤 지정 생성자가 존재하는지?
(상위) 지정 생성자 | 1) 하위클래스에서 지정 생성자로 구현 (재정의) |
2) 하위클래스에서 편의 생성자로 구현 가능 (재정의) | |
3) 구현 안 해도 됨(반드시 재정의하지 않아도 됨) | |
(상위) 편의 생성자 | 재정의를 하지 않아도 됨 (호출 불가가 원칙이기 때문에 재정의 제공 안 함) |
(만약에 동일한 이름을 구현했다면) 그냥 새로 정의한 것임 |
[2단계 - (현재단계의) 생성자 구현]
1) 지정 생성자 내에서 | 1) 나의 모든 저장 속성을 초기화해야 함 |
2) 슈퍼 클래스의 지정 생성자 호출 | |
2) 편의 생성자 내에서 | 현재 클래스의 지정생성자 호출 해야 함 (편의 생성자를 거치는 것은 상관없음) |
결국 지정 생성자만 모든 저장 속성을 초기화 가능 |
class Monster {
var hp = 10
// 기본생성자가 자동으로 제공됨
//init() { }
}
let snail = Monster()
print("달팽이의 체력은 \(snail.hp)")
----------------------
//상위 클래스의 생성자 종류
// init()
class Monster {
var hp = 10
// 기본생성자가 자동으로 제공됨
//init() { }
}
let snail = Monster()
print("달팽이의 체력은 \(snail.hp)")
class Boss: Monster {
var skils: String
// 1. 상위의 지정생성자를 고려
// init()
// 선택1. 지정생성자로 재정의
// 상위클래스의 이름이 동일한 생성자 구현은 재정의만 가능
// override init() {
// // 1.나의 모든 저장속성 초기화
// self.skils = "Lumos"
// //2. 슈퍼 클래스의 지정생성자 호출
// super.init()
// }
// 선택2 하위클래스에서 편의생성자로 구현
// 상위클래스의 이름이 동일한 생성자 구현은 재정의만 가능
override convenience init() {
//편의생성자를 구현했기 때문에 지정생성자 호출
self.init(skils: "Lumos")
}
// 2. 현재단계의 생성자 구현
init(skils: String) {
self.skils = skils
super.init()
}
// 선택3 재정의를 하지 않을 수도 있음
}
- 하위 클래스에서 지정생성자와 슈퍼클래스의 생성자를 지정생성자로 재정의한 구조
애플 공식 문서 예제
class Vehicle {
var numberOfWheels = 0
var description: String {
return "\(numberOfWheels) wheel(s)"
}
// init() { }
}
// numberOfWheels의 저장 속성에 기본값을 제공, 생성자 구현하지 않았으므로
// ===> 기본 생성자 init() 자동제공
let vehicle = Vehicle()
print("Vehicle: \(vehicle.description)") // Vehicle: 0 wheel(s)
// 상위의 지정생성자
// init()
// 서브클래스 정의
class Bicycle: Vehicle {
override init() {
super.init() // 수퍼클래스 호출 반드시 필요
numberOfWheels = 2 // 초기화의 2단계 값설정
}
}
// 커스텀 init() 정의 ===> 생성자가 상위클래스의 이름과 동일 하므로 재정의 키워드 필요
// 상위 지정생성자 호출하여 메모리 초기화 후, 상위에서 구현한 속성에 접근하여 2로 셋팅(2단계 값설정)
let bicycle = Bicycle()
print("Bicycle: \(bicycle.description)") // Bicycle: 2 wheel(s)
// 상위의 지정생성자
// init()
// 서브클래스 정의
class Hoverboard: Vehicle {
var color: String
// (읽기) 계산 속성 재정의
override var description: String {
return "\(super.description) in a beautiful \(color)"
}
// override init() { //오버라이딩 가능
// self.color = "파란색"
// super.init()
// }
// override convenience init() { // 편의 생성자는 나의 지정생성자 호출
// self.init(color: "파란색")
// }
init(color: String) { // 저장속성이 있기 때문에, 새로운 지정생성자 생성 필요
self.color = color // (현재 클래스) 저장 속성 초기화
//super.init() // =====> 여기서 암시적으로 호출됨
}
}
// 생성자에서 Hoverboard 클래스는 색상 속성만 설정
// 2단계 값설정(커스텀)없고, 상위구현에 기본 init() 만 있는 경우 생략가능(암시적 요청)
let hoverboard = Hoverboard(color: "silver")
print("Hoverboard: \(hoverboard.description)") // Hoverboard: 0 wheel(s) in a beautiful silver
생성자의 상속/재정의 정리
- 하위클래스에서는 기본적으로 상위클래스의 생성자를 상속하지 않고, 재정의하는 것이 원칙입니다.
- 올바르게 초기화되지 않을 수 있는 가능성을 배제하는 것입니다. - 하위클래스에 최적화가 안되어 있음.
-> 예외적으로, 안전한 경우에만 상위 클래스의 생성자가 자동으로 상속됩니다. - 재정의란 동일한 이름을 가진 생성자를 구현하는 것입니다.
- 하위클래스의 커스텀 생성자 구현하기 전에 (상위클래스의) 재정의 생성자를 작성해야 실수하지 않습니다.
728x90
'iOS > Swift 문법' 카테고리의 다른 글
필수생성자(Required Initializers) (0) | 2024.12.06 |
---|---|
클래스의 지정, 편의 생성자 상속의 예외사항(자동상속) (0) | 2024.12.06 |
지정생성자와 편의 생성자 위임 규칙 (0) | 2024.12.06 |
지정생성자와 편의생성자 (0) | 2024.11.28 |
초기화(Initialization)와 생성자(Initializer) (0) | 2024.11.27 |