[swift] Class 이니셜라이져

2023. 3. 1. 21:54👩🏻‍💻 ios 앱개발 ( swift )

728x90

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가 없다고 오류

자식에서 부모의 initializer를 꼭 불러줘야함.  -> super.init

안해주면 부모 property에 접근할 수 없기 때문

 

super가 self 앞에 오면 에러가 발생한다. -> 이를 이해하기 위해서 2- phase Initialization 에 대해 알아야한다.

 

🫥 2- phase Initialization

swift에는 2- phase Initialization 라는 규칙이 있다.

이상동작을 방지하기 위한 규칙

 

[phase1]

- 아래에서 위로 initialize

- 자식꺼 먼저 initialize

- phase1 이 끝나기 전에는 어떠한 property나 method도 사용할 수 없다.

- 세팅되기 전의 property를 사용하면 문제가 생길것이기때문

sports 를 먼저 init 후 person 관련 init

 

[phase2]

- phase1과 반대방향으로 감

- self.init과 super.init이 모두 끝나고 난 후의 진행

- self.init과 super.init이 모두 끝나면 property와 메서드들을 사용할 수 있는 상태가 됨.

 

init이 끝나기 전에는 메서드를 쓸 수 없다

phase2에 해당하는 작업을 phase1에서 하려고 하면 오류가 난다

 

🫥

지정된 initializer가 필요하다.

상속받을 경우 따로 init을 만들지 않아도 된다. ( 부모의 initializer가 있기 때문 )

특수한 상황에서만 자식 안에 init 만들어줌

 

Student 내에서의 super.init과 StudentAthlete의 super.init의 모양이 다름. 당황

부모 class에서 지정 initializer를 설정해줘야한다.  -> required

 

 

self.sports를 초기화해주라고 난리

상속관계에서

자식은 따로 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