2023. 3. 1. 21:54ㆍ👩🏻💻 ios 앱개발 ( swift )
Person
Student
StudentAthlete
FootballPlayer
import UIKit
struct Grade {
var letter: String
var points: Double
var credits: Double
}
class Person {
var firstName: String
var lastName: String
init(firstName: String, lastName: String){
self.firstName = firstName
self.lastName = lastName
}
func printMyName(){
print("My name is \(firstName) \(lastName)")
}
}
class Student: Person {
var grades: [Grade] = []
func recordGrade(_ grade: Grade){
grades.append(grade)
}
}
class StudentAthlete: Student {
var minimumTrainingTime: Int = 2
var trainedTime: Int = 0
func train(){
trainedTime += 1
}
}
class FootballPlayer: StudentAthlete {
var footballTeam = "FC Swift"
override func train() {
trainedTime += 2
}
}
자식에서 부모의 initializer를 꼭 불러줘야함. -> super.init
안해주면 부모 property에 접근할 수 없기 때문
super가 self 앞에 오면 에러가 발생한다. -> 이를 이해하기 위해서 2- phase Initialization 에 대해 알아야한다.
🫥 2- phase Initialization
swift에는 2- phase Initialization 라는 규칙이 있다.
이상동작을 방지하기 위한 규칙
[phase1]
- 아래에서 위로 initialize
- 자식꺼 먼저 initialize
- phase1 이 끝나기 전에는 어떠한 property나 method도 사용할 수 없다.
- 세팅되기 전의 property를 사용하면 문제가 생길것이기때문
[phase2]
- phase1과 반대방향으로 감
- self.init과 super.init이 모두 끝나고 난 후의 진행
- self.init과 super.init이 모두 끝나면 property와 메서드들을 사용할 수 있는 상태가 됨.
phase2에 해당하는 작업을 phase1에서 하려고 하면 오류가 난다
🫥
지정된 initializer가 필요하다.
상속받을 경우 따로 init을 만들지 않아도 된다. ( 부모의 initializer가 있기 때문 )
특수한 상황에서만 자식 안에 init 만들어줌
Student 내에서의 super.init과 StudentAthlete의 super.init의 모양이 다름. 당황
부모 class에서 지정 initializer를 설정해줘야한다. -> required
상속관계에서
자식은 따로 initializer를 만들지 않아도 부모의 지정 initializer를 사용하게 됨.
자식에서 새로운 initializer를 만들어줬다면 required 키워드를 이용해서 지정 initializer를 만들어주면됨.
🫥 convenience init
required init을 만들때 좀 더 간편하게 도와줌
class Student: Person {
var grades: [Grade] = []
//지정 initializer
required init(firstName: String, lastName: String) {
super.init(firstName: firstName, lastName: lastName)
}
// 전학생이 왔다!
convenience init(transfer: Student) {
//self.init : required initializer
self.init(firstName: transfer.firstName, lastName: transfer.lastName)
}
func recordGrade(_ grade: Grade){
grades.append(grade)
}
}
convenience init을 통해서 required init을 호출
🫥 designated(지정 이니셜라이져) vs. convenience
- DI는 자신의 부모의 DI를 호출해야함
- CI는 같은 클래스의 이니셜라이저를 꼭 하나 호출해야함
- CI는 궁극적으로는 DI를 호출해야함
'👩🏻💻 ios 앱개발 ( swift )' 카테고리의 다른 글
[swift] Class 상속 (0) | 2023.02.27 |
---|---|
[swift] Class vs. Structure (0) | 2023.02.27 |
[swift] Closure & Collection **연습하기(reduce, filter, map) (3) | 2023.02.24 |
[swift] Closure (0) | 2023.02.22 |
[swift] Collection (1) | 2023.02.17 |