study record
[Swift] 상속 본문
어떤 클래스로부터 상속을 받으면 상속받은 클래스는 그 어떤 클래스의 자식클래스라고 표현한다. 자식클래스에게 자신의 특성을 물려준 클래스를 부모클래스라고 표현한다. 상속은 스위프트의 다른 타입과 클래스를 구별 짓는 클래스만의 특징이다.
스위프트의 클래스는 부모클래스로부터 물려받은 메서드를 호출할 수 있고 프로퍼티에 접근할 수 있으며 서브스크립트도 사용할 수 있다. 또, 부모클래스로부터 물려받은 메서드, 프로퍼티, 서브스크립트 등을 자신만의 내용으로 재정의할 수도 있다. 스위프트는 부모클래스의 요소를 자식클래스에서 재정의할 때 자식클래스가 부모클래스의 요소들을 재정의한다는 것을 명확히 확인해주어야 한다.
상속받은 프로퍼티에 프로퍼티의 값이 변경되었을 때 알려주는 프로퍼티 감시자도 구현할 수 있다. 연산 프로퍼티를 정의해준 클래스에서는 연산 프로퍼티에 감시자를 구현할 수 없지만, 부모클래스에서는 어떤 프로퍼티든 자식클래스에서 프로퍼티 감시자를 구현할 수 있다.
다른 클래스로부터 상속을 받지 않은 클래스를 기반클래스라고 부른다.
클래스 상속
상속은 기반클래스를 다른 클래스에서 물려받는 것을 말한다. 부모클래스의 메서드, 프로퍼티 등을 재정의하거나 기반클래스의 기능이나 프로퍼티를 물려받고 자신의 기능을 추가할 수 있다.
클래스 이름 뒤에 콜론을 붙이고 다른 클래스 이름을 써주면 뒤에 오는 클래스의 기능을 앞의 클래스가 상속받을 것임을 뜻한다.
class 클래스 이름: 부모클래스 이름 {
프로퍼티와 메서드들
}
다른 클래스를 상속받으면 똑같은 기능을 구현하기 위하여 코드를 다시 작성할 필요가 없으므로 코드를 재사용하기 용이하고 더불어 기능을 확장할 때 기존 클래스를 변경하지 않고도 새로운 추가 기능을 구현한 클래스를 정의할 수 있다.
재정의
자식 클래스는 부모클래스로부터 물려받은 특성(인스턴스 메서드, 타입 메서드, 인스턴스 프로퍼티, 타입 프로퍼티, 서브스크립트 등)을 그대로 사용하지 않고 자신만의 기능으로 변경하여 사용할 수 있다. 이를 재정의(Override)라고 한다.
상속받은 특성들을 재정의하려면 새로운 정의 앞에 override 키워드를 사용한다. override 키워드는 스위프트 컴파일러가 조상클래스(부모를 포함한 그 상위 부모클래스)에 해당 특성이 있는지 확인한 후 재정의하게 된다. 만약 조상클래스에 재정의할 해당 특성이 없는데 키워드를 사용하면 컴파일 오류가 발생한다.
만약 자식클래스에서 부모클래스의 특성을 재정의했을 때, 부모클래스의 특성을 자식클래스에서 사용하고 싶다면 super 프로퍼티를 사용하면 된다. 즉, 자식클래스에서 특성을 재정의했지만 필요에 따라 부모클래스의 특성을 활용하고 싶을 때 super를 사용한다. super 키워드를 타입 메서드 내에서 사용한다면 부모클래스의 타입 메서드와 타입 프로퍼티에 접근할 수 있으며 인스턴스 메서드 내에서 사용한다면, 부모클래스의 인스턴스 메서드와 인스턴스 프로퍼티, 서브스크립트에 접근할 수 있다.
재정의한 someMethod()의 부모 버전을 호출하고 싶다면 super.someMethod()라고 호출하면 된다. 재정의한 someProperty의 부모 버전에 접근하고 싶다면 super.someProperty 라고 접근하면 된다. 재정의한 서브스크립트에서 부모 버전의 서브스크립트로 접근하고 싶다면 super[index]라고 접근하면 된다.
메서드 재정의
class Student: Person {
var grade: String = "F"
override func speak() {
print("저는 학생입니다.")
}
}
class UniversityStudent: Student {
var major: String = ""
class func introduceClass() {
print(super.introduceClass())
}
override class func introduceClass() -> String {
return "대학생의 소원은 A+"
}
override func speak() {
super.speak()
print("대학생이죠")
}
}
let jay: Student = Student()
jay.speak() //저는 학생입니다.
let jenny: UniversityStudent = UniversityStudent()
jenny.speak() // 저는 학생입니다. 대학생이죠
print(UniversityStudent.introduceClass() as String) // 대학생의 소원은 A+
UniversityStudent.introduceClass() as Void // 인류의 소원은 평화입니다.
Student 클래스에서 Person 클래스에 정의된 speak() 메서드를 재정의했고, UniversityStudent 클래스에서는 Person 클래스의 introduceClass() 메서드를 재정의했다. Student 클래스에서 재정의한 speak() 메서드는 UniversityStudent 클래스로 상속되었으므로 UniversityStudent 클래스의 인스턴스는 speak() 메서드를 호출하면 Student 클래스에서 재정의한 메서드가 호출된다.
UniversityStudent 클래스의 introduceClass() 메서드에 override 키워드가 붙은 메서드와 그렇지 않은 메서드가 두 가지가 있는 것은 반환 타입이 다르기 때문이다. 스위프트는 메서드의 반환타입이나 매개변수가 다르면 서로 다른 메서드로 취급한다. 서로 다른 타입의 반환 값을 받아오기 위해 as 연산자를 사용한다.
부모클래스의 메서드에 접근하기 위해서는 super 프로퍼티를 사용하면 된다.
'Swift > 스위프트 프로그래밍' 카테고리의 다른 글
[Swift] 프로토콜 (0) | 2022.01.11 |
---|---|
[Swift] 타입 캐스팅 (0) | 2022.01.06 |
[Swift] 서브스크립트 (0) | 2021.12.26 |
[Swift] 모나드 (0) | 2021.12.06 |
[Swift] 맵, 필터, 리듀스 (0) | 2021.12.03 |