안녕하세요! 피피아노입니다🎵
이번 포스팅에서도 저번에 이어서 초기화(Initializers)에 대해 정리를 해볼텐데 이번에는 초기화 중에서 상속과 재정의에 대해서 알아보도록 하겠습니다!
그럼 바로 시작하겠습니다.
이니셜라이저 상속과 재정의
Swift에서 이니셜라이저는 기본적으로 부모 클래스로부터 상속되지 않는 특성을 가지고 있습니다. 이는 자식 클래스가 부모 클래스의 이니셜라이저를 그대로 사용할 경우, 자식 클래스의 새로운 인스턴스가 완벽하게 초기화되지 않는 문제를 예방하기 위함입니다.
그러나, 특별한 상황에서는 부모 클래스의 이니셜라이저가 자동으로 상속되기도 합니다.(이 내용은 아래에서 다시 설명하도록 하겠습니다)
만약 자식 클래스에서 부모 클래스의 이니셜라이저를 사용하고자 한다면, 동일한 이니셜라이저를 자식 클래스에서 직접 구현해주면 됩니다.
부모 클래스와 동일한 지정 이니셜라이저를 자식 클래스에서 사용하려면, 해당 이니셜라이저를 재정의(override)하면 됩니다.
이 때, override 키워드를 사용해야 합니다. 클래스의 기본 이니셜라이저나 자식 클래스의 편의 이니셜라이저가 부모 클래스의 지정 이니셜라이저를 재정의하는 경우에도 마찬가지입니다.
그러나, 부모 클래스의 편의 이니셜라이저와 동일한 이니셜라이저를 자식 클래스에서 구현하려 할 때는 override 키워드를 사용하지 않아야 합니다. 그 이유는 자식 클래스에서 부모 클래스의 편의 이니셜라이저를 호출할 수 없기 때문입니다. 따라서, 이를 재정의할 필요가 없습니다.
클래스 이니셜라이저 재정의 코드
class Vehicle {
var speed: Double
init(speed: Double) {
self.speed = speed
}
}
class Car: Vehicle {
var gear: Int
override init(speed: Double) {
self.gear = 1
super.init(speed: speed)
}
}
let myCar = Car(speed: 100.0)
print(myCar.speed) // 출력: 100.0
print(myCar.gear) // 출력: 1
우리가 여기서 다루는 건 'Vehicle'이라는 부모 클래스와, 그걸 상속받은 'Car'라는 자식 클래스입니다. 'Vehicle' 클래스에는 'speed'라는 속성이 있습니다. 그리고 'Car' 클래스는 'Vehicle' 클래스가 가진 'speed' 속성 외에도 'gear'라는 속성을 추가로 가지고 있습니다.
자, 그럼 각 클래스의 초기화를 어떻게 하는지 살펴보겠습니다.
'Vehicle' 클래스는 'speed'를 초기화하는데, 'Car' 클래스는 조금 다르게 동작합니다. 'Car' 클래스는 자신만의 'gear' 속성을 먼저 초기화한 후, 'super.init(speed: speed)'를 이용해서 부모 클래스인 'Vehicle'의 'speed'도 초기화하게 됩니다. 이렇게 하면 'Car' 클래스의 인스턴스를 만들 때 'speed'와 'gear' 둘 다 원하는 값으로 설정할 수 있게 되는 거죠.
마지막으로 'myCar'라는 'Car' 클래스의 인스턴스를 만들고, 그 'speed'와 'gear' 값을 출력해 보면, 각각 100.0과 1이 나오게 됩니다. 이 값들은 'Car' 클래스의 초기화 과정에서 설정한 값이랑 똑같습니다.
직접 자동차를 만드는 것처럼 생각해보면. 'Vehicle' 클래스는 자동차의 기본적인 요소인 'speed'를 설정하고, 'Car' 클래스는 그 위에다가 'gear'라는 추가적인 요소를 더하는 것입니다. 이렇게 각 클래스가 자신의 역할을 수행하면서, 결국 'myCar'라는 완성된 자동차가 만들어지게 됩니다.
'Vehicle' 클래스를 상속받은 'Car' 클래스에서 부모클래스의 편의 이니셜라이저와 동일한 편의 이니셜라이저를 정의할 때 override 수식어를 붙이지 않은 것을 볼 수 있습니다.
반대로 지정 이니셜라이저는 재정의를 위해 override 수식어를 사용한 것을 볼 수 있습니다. 기본 이니셜라이저 외에 지정 이니셜라이저를 자식클래스에서 동일한 이름으 로 정의하려면 재정의를 위한 override 수식어를 명시해주어야 합니다.
부모클래스의 실패 가능한 이니셜라이저를 자식클래스에서 재정의하고 싶을 때는 실패 가능한 이니셜라이저로 재정의해도 되고 필요에 따라서 실패하지 않는 이니셜라이저로 재정의 해줄 수도 있습니다. 실패 가능한 이니셜라이저도 추후 정리해서 포스팅 하도록 하겠습니다!
이니셜라이저 자동 상속
Swift의 이니셜라이저는 부모 클래스의 이니셜라이저를 상속받지 않는다고 했습니다. 하지만 특정 조건을 만족한다면 부모 클래스의 이니셜라이저가 자동으로 상속될 수 있습니다.
이니셜라이저의 자동 상속에는 2가지 규칙이 있습니다.
규칙 1
부모 클래스에서 기본 이니셜라이저를 제공하면, 자식 클래스에서 별도의 이니셜라이저를 정의하지 않는 한 부모 클래스의 기본 이니셜라이저가 자동으로 상속됩니다. 이 말은, 부모 클래스의 모든 저장 프로퍼티에 기본값이 제공되는 경우에 해당합니다.
규칙 2
자식 클래스가 부모 클래스의 모든 지정 이니셜라이저를 상속하거나 재정의했다면, 부모 클래스의 편의 이니셜라이저도 자동으로 상속됩니다. 이 말은, 자식 클래스가 부모 클래스의 모든 이니셜라이저를 상속받거나 재정의해야만 부모 클래스의 편의 이니셜라이저를 상속받을 수 있다는 것을 의미합니다.
class Animal {
var name: String
init(name: String) {
self.name = name
}
convenience init() {
self.init(name: "Unknown")
}
}
class Dog: Animal {
var breed: String = "Unknown Breed"
}
// 부모 클래스의 지정 이니셜라이저 자동 상속
let elephant: Animal = Animal(name: "Elephant")
let fido: Dog = Dog(name: "Fido")
print(elephant.name) // Elephant
print(fido.name) // Fido
// 부모 클래스의 편의 이니셜라이저 자동 상속
let unknownAnimal: Animal = Animal()
let unknownDog: Dog = Dog()
print(unknownAnimal.name) // Unknown
print(unknownDog.name) // Unknown
이 코드에서 Animal 클래스는 name이라는 프로퍼티와 두 개의 이니셜라이저를 가지고 있습니다. 하나는 name을 입력받는 지정 이니셜라이저이고, 다른 하나는 name에 "Unknown"을 할당하는 편의 이니셜라이저입니다.
Dog 클래스는 Animal 클래스를 상속받아 name 프로퍼티를 상속받고, 추가로 breed라는 새로운 프로퍼티를 가지고 있습니다. Dog 클래스는 부모 클래스인 Animal의 이니셜라이저를 상속받습니다.
따라서 Dog(name: "Fido")와 같이 name을 입력받는 이니셜라이저를 사용하여 Dog 클래스의 인스턴스를 생성할 수 있고, Dog()와 같이 편의 이니셜라이저를 사용하여 name에 "Unknown"을 할당하는 인스턴스를 생성할 수도 있습니다.
이번 포스팅에서는 이니셜라이저의 상속과 재정의에 대해서 정리해보았습니다.
다음 포스팅에서는 이번 시간에는 못 다룬 실패 가능한 이니셜라이저 요구 이니셜라이저에 대해서 정리를 해보도록 하겠습니다!
감사합니다.
잘못된 내용이 있거나 더 좋은 내용 피드백은 언제나 환영합니다!
궁금하신 부분은 댓글로 질문 부탁드립니다!
'Apple > Swift' 카테고리의 다른 글
[Swift] 초기화(Initializers) 알아보기 (6) - Failable Initalizers (0) | 2024.02.22 |
---|---|
[Swift] 초기화(Initializers) 알아보기 (5) - 요구 이니셜라이저 (0) | 2024.02.16 |
[Swift] 초기화(Initializers) 알아보기 (3) - 2단계 초기화 (0) | 2024.02.06 |
[Swift] 초기화(Initializers) 알아보기 (2) - 구조체, Memberwise, 클래스의 초기화, 지정/편의 초기화 (0) | 2024.02.04 |
[Swift] 초기화(Initializers) 알아보기 (1) - 초기화의 개념과 사용 방법, 규칙 (0) | 2024.01.29 |