/**
지정생성자/ 편의생성자 상속의 예외사항
*/
/**
지정생성자 자동상속의 예외 상황 -> 저장속성의 기본값 설정
- 새 저장 속성이 아예 없거나, 기본값이 설정되어 있다면 (실패 가능성 배제)
===> 슈퍼클래스의 지정생성자 모두 자동 상속(하위에서 어떤 재정의도 하지 않으면)
*/
/**
편의 생성자 자동상속의 예외 상황 -> 상위지정생성자 모두 상속
(초기화 실패 가능성 배제시) 자동 상속
- 1. 지정 생성자 자동으로 상속하는 경우
- 2. 상위 지정생성자 모두 재정의 구현 (실패 가능성 배제)
(결국, 모든 지정생성자를 상속하는 상황이 되면 편의생성자는 자동으로 상속됨)
*/
/**
지정 생성자와 편의 생성자의 실제 사례 - 애플 공식 문서
*/
class Food {
var name: String
init(name: String) { // 지정 생성자
self.name = name
}
convenience init() { // 편의 생성자 ==> 지정 생성자 호출
self.init(name: "[Unamed]")
}
}
let namedMeat = Food(name: "Bacon") // namedMeat 의 이름은 "Bacon"
namedMeat.name
let mysteryMeat = Food() // mysteryMeat 의 이름은 "[Unnamed]"
mysteryMeat.name
// 상위의 지정생성자 🤙🏻
// init(name: String) 지정생성자
// convenience init() 편의생성자
// 레시피 재료
class RecipeIngredient: Food {
var quantity: Int
init(name: String, quantity: Int) { // 모든 속성 초기화
self.quantity = quantity
super.init(name: name)
}
override convenience init(name: String) { // 상위 지정 생성자를 편의 생성자로 재정의 ==> 지정 생성자 호출
self.init(name: name, quantity: 1)
}
// convenience init() { } // 자동 상속 (예외 규칙)
}
let oneMysteryItem = RecipeIngredient()
let oneBacon = RecipeIngredient(name: "Bacon")
let sixEggs = RecipeIngredient(name: "Eggs", quantity: 6)
// 상위의 지정생성자 🤙🏻
// init(name: String, quantity: Int) 지정생성자
// convenience init(name: String) {} 편의생성자
// convenience init() 편의생성자
// 쇼핑아이템 리스트
class ShoppingListItem: RecipeIngredient {
var purchased = false // 모든 저장속성에 기본값 설정
var description: String {
var output = "\(quantity) x \(name)"
output += purchased ? " ✔": " x"
return output
}
// init(name: String, quantity: Int) {} // 지정생성자 모두 자동상속
// convenience init(name: String) {} // 따라서 ==> 편의상속자도 모두 자동 상속됨
// convenience init() {} // 따라서 ==> 편의상속자도 모두 자동 상속됨
}
var breakfastList = [
ShoppingListItem(),
ShoppingListItem(name: "Bacon"),
ShoppingListItem(name: "Eggs", quantity: 6),
]
breakfastList[0].name
breakfastList[0].purchased = true
for item in breakfastList {
print(item.description)
}
/*
출력
1 x [Unamed] ✔
1 x Bacon x
6 x Eggs x
*/