[Swift] 초기화 (Initializer) - 3

이니셜라이저 마지막 포스팅으로
상속에 따라 재정의는 어떻게 되는지 알아보도록 하죠 🤔

클래스의 이니셜라이저 - 상속과 재정의

기본적으로 스위프트의 이니셜라이저는 부모클래스의 이니셜라이저를 상속받지 않는다.

부모클래스로부터 물려받은 이니셜라이저는 자식클래스에 최적화되어 있지 않아서, 부모클래스의 이니셜라이저를 사용했을 때 자식클래스의 새로운 인스턴스가 완전하고 정확하게 초기화되지 않는 상황을 방지하고자 함이다.

하지만, 안전하고 적절하다고 판단되는 특정한 상황에서는 부모클래스의 이니셜라이저가 상속될 수 있다.

상속에 따른 재정의

부모클래스와 동일한 "지정 이니셜라이저"

부모클래스와 동일한 지정 이니셜라이저를 자식클래스에서 구현해주러려면 재정의하면 되는데,
override 수식어를 사용하면 되며, 클래스에 주어지는 기본 이니셜라이저를 재정의 할 때도 마찬가지이다.

자식클래스의 "편의 이니셜라이저"가 부모클래스의 "지정 이니셜라이저"

자식클래스의 편의 이니셜라이저가 부모클래스의 지정 이니셜라이저를 재정의 하는 경우에도 override 수식어를 붙여준다.

부모클래스의 "편의 이니셜라이저"와 동일한 자식클래스의 "이니셜라이저"

부모클래스의 편의 이니셜라이저와 동일한 이니셜라이저를 자식클래스에 구현할 때는 override 수식어를 붙이지 않는다.
자식클래스에서 부모클래스의 편의 이니셜라이저는 절대로 호출할 수 없기 때문에 재정의 할 필요성이 없다.

부모클래스의 "실패 가능한 이니셜라이저"를 자식클래스에서 재정의

부모클래스의 실패 가능한 이니셜라이저를 자식클래스에서 재정의하고 싶을 때는
실패 가능한 이니셜라이저로 재정의해도 되고 필요에 따라서 실패하지 않는 이니셜라이저로 재정의 해도된다.


자동 상속

기본적으로 스위프트의 이니셜라이저는 부모클래스의 이니셜라이저를 상속받지 않는다고 했다.

그러나 특정 조건에 부합한다면 부모클래스의 이니셜라이저가 자동으로 상속된다.
사실... 대부분의 경우 자식클래스에서 이니셜라이저를 재정의해줄 필요가 없다.

특정 조건

자식클래스에서 프로퍼티 기본값을 모두 제공한다고 가정했을 때,

  • [규칙1] : 자식클래스에서 별도의 지정 이니셜라이저를 구현하지 않는다면, 부모클래스의 지정 이니셜라이저가 자동으로 상속된다.
  • [규칙2] : 만약 [규칙1]에 따라 자식클래스에서 부모클래스의 지정이니셜라이저를 자동으로 상속받은 경우 또는 부모클래스의 지정 이니셜라이저를 모두 재정의하여 부모클래스와 동일한 지정 이니셜라이저를 모두 사용할 수 있는 상황이라면 부모클래스의 편의 이니셜라이저가 모두 자동으로 상속된다.

class Person {
    var name: String
    
    init(name: String) {
        self.name = name
    }
    
    convenience init() {
        self.init(name: "Camper")
    }
}

class Student: Person {
    var major: String = "Swift"
}

// 부모클래스의 지정 이니셜라이저 자동 상속
let fezz = Person(name: "fezz") // fezz
let yagom = Student(name: "yagom") // yagom

// 부모클래스의 편의 이니셜라이저 자동 상속
let Tak = Person() // Camper
let Tic = Student() // Camper

요구 이니셜라이저

required 수식어를 클래스의 이니셜라이저 앞에 명시해주면
이 클래스를 상속받은 자식클래스에서 반드시 해당 이니셜라이저를 구현해주어야한다.

부모클래스의 일반 이니셜라이저를 자신의 클래스부터 요구 이니셜라이저로 변경할 수도있다.

class Person {
    var name: String
    
    // 요구 이니셜라이저 정의
    required init() {
        self.name = "Camper"
    }
}

class Student: Person {
    var major: String = "Unknown"
    
    // 자신의 지정 이니셜라이저 구현
    init(major: String) {
        self.major = major
        super.init()
    }
    
    // 요구 이니셜라이저 정의
    required init() {
        self.major = "Camper"
        super.init()
    }
}

class UniversityStudent: Student {
    var grade: String
    
    // 자신의 지정 이니셜라이저 구현
    init(grade: String) {
        self.grade = grade
        super.init()
    }
    
    required init() {
        self.grade = "F"
        super.init()
    }
}

let jisoo = Student()
print(jisoo.major) // Camper

let jenny = Student(major: "iOS")
print(jenny.major) // iOS

let fezz = UniversityStudent(grade: "A+")
print(fezz.grade) // A+


📄 참고
[도서] 스위프트 프로그래밍 3판 - 야곰

좋은 웹페이지 즐겨찾기