목차
- 자식클래스가 새로운 형태로 Initializer를 만드는 방법
- 2-phase Initialization (클래스 생성시 2단계)
- 상속이 깊어지면 Initializer에 전달하는 파라미터의 갯수도 늘어난다.
- 규칙
- code
1. 자식클래스가 새로운 형태로 Initializer를 만드는 방법
init(firstName: String, lastName: String, sports:[String]){
self.sports = sports
super.init(firstName:firstName, lastName:lastName)
// 여기서 Stored Property를 먼저 초기화한 다음에 상위 클래스의 생성자를 호출하는 것이 관례이다. 이유는 2에서 알려줄께
}
// 이렇게 되면 해당 클래스의 생성자에 맞게 파라미터를 전달하면 된다.
2. 2-phase Initialization(클래스 생성시 2단계)
자식클래스의 Stored Property부터 초기화하고 부모클래스의 생성자를 호출해야한다.
Class에서 모든 Stored Property가 초기화 된 상태에서만 Method를 호출할 수 있도록 하여 코드의 안정성을 높이고 오류를 줄이기 위함이다. --> 실제 상위 클래스의 생성자부터 호출하면 오류가 발생한다.
- 모든 Stored Property가 초기화 된 상태여야 어떤 Method를 호출 가능하기에, 현재 클래스의 Stored Property를 초기화하고, 상위클래스의 Stored Property를 초기화하기 위한 생성자를 호출한다.
- 이제 모든 Stored Property가 초기화 되었기에 원하는 Method를 호출한다.
결론: 모든 Stored Property가 초기화 되지 않은 상태에서 어떤 Method를 호출하게 되면 오류발생!!
3. 상속이 깊에지면 Initializer에 전달하는 파라미터의 갯수도 늘어난다.
다음과 같이 간단한 형태의 initialization을 정의할 수 있다.
이렇게 축소하고 간편하게 쓸수있게 만든 Initializer을 convenience initializer(보조 생성자)라고 한다.
--> 근데 결국 이 보조 생성자 안에서 기본값이더라도 전체 초기화작업은 한다.
--> 그래서 보조생성자(convenience initializer: 간편생성자)의 경우 메인생성자(designated initialization: 지정생성자)가 따로 반드시 존재해야하고, 그 생성자를 호출하는 형식으로 이용된다.
--> 그렇기에 Class의 객체를 생성할 때, 원하는 파라미터를 전달하도록 조작이 가능하다.
4. 규칙
여기서 규칙을 정해줄게 (DI: Designated Initialzation, CI: Convenience Initialization)
- DI는 자신의 DI를 호출해야한다.
- CI는 같은 클래스의 이니셜라이즈를 꼭 하나 호출 해야한다.
- CI는 궁극적으로는 DI를 호출해야한다.
5. Code
// struct Grade {
// var letter: Character
// 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] = []
// }
// // 학생인데 운동선수
// 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
// }
// }
struct Grade {
var letter: Character
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] = []
override init(firstName: String, lastName: String) {
super.init(firstName: firstName, lastName: lastName)
}
convenience init(student: Student) {
self.init(firstName: student.firstName, lastName: student.lastName)
}
}
// 학생인데 운동선수
class StudentAthlete: Student {
var minimumTrainingTime: Int = 2
var trainedTime: Int = 0
var sports: [String] // 운동선수의 스포츠 기술
// class에서 stored property를 새로 선언하면, 생성하는 시점에 꼭 초기화될 값을 주어야한다.
init(firstName: String, lastName: String, sports:[String]){
// Phase 1
self.sports = sports
super.init(firstName:firstName, lastName:lastName)
// Phase 2
self.train()
}
convenience init(name: String){
self.init(firstName: name, lastName: "", sports: [])
}
func train() {
trainedTime += 1
}
}
// 운동선인데 축구선수
class FootballPlayer: StudentAthlete {
var footballTeam = "FC Swift"
override func train() {
trainedTime += 2
}
}
let student1 = Student(firstName: "Cho", lastName: "yeong")
let student1_1 = Student(student: student1)
let student2 = StudentAthlete(firstName: "U", lastName: "dong", sports:["기무라"])
let student3 = StudentAthlete(name: "안뇽")
'Toy Project > Swift Language Syntax' 카테고리의 다른 글
15. Swift Class Inheritance (상속) (0) | 2021.01.22 |
---|---|
14. Swift Class (0) | 2021.01.22 |
13. Swift Method extension (0) | 2021.01.22 |
12. Swift Method (0) | 2021.01.22 |
11. Swift Property(속성) (0) | 2021.01.21 |