개발자의 삽질
[Swift] Inheritance 본문
https://docs.swift.org/swift-book/LanguageGuide/Inheritance.html
오늘은 Inheritance에 대해 알아보자
클래스는 메서드, 프로퍼티 또는 다른 클래스의 다른 특징들을 상속 할 수 있다. 어떤 클래스(A)가 다른 클래스(B)를 상속받는다면, 상속받게 되는 클래스(A)는 Subclass 가 되고 상속하는 클래스(B)를 SuperClass가 된다.
Defining a Base Class
다른 클래스의 상속을 받지 않는 클래스를 base class 라고 한다.
class Vehicle {
var currentSpeed = 0.0
var description: String {
return "traveling at \(currentSpeed) miles per hour"
}
func makeNoise() {
// do nothing - an arbitrary vehicle doesn't necessarily make a noise
}
}
let someVehicle = Vehicle()
print("Vehicle: \(someVehicle.description)")
// Vehicle: traveling at 0.0 miles per hour
Subclassing
SubClassing 이란 기존에 있던 클래스를 기반으로 새로운 클래스를 만드는 것이다. 서브 클래스는 기존의 클래스가 갖고 있는 수정 가능한 특성들을 갖게 된다. 또한, 새로운 특성들을 추가할 수 있다.
class SomeSubclass: SomeSuperclass {
// subclass definition goes here
}
class Bicycle: Vehicle {
var hasBasket = false
}
let bicycle = Bicycle()
bicycle.hasBasket = true
bicycle.currentSpeed = 15.0
print("Bicycle: \(bicycle.description)")
// Bicycle: traveling at 15.0 miles per hour
Bicycle 은 Vehicle 이 가진 특성들(currentSpeed, description 프로퍼티, makeNoise() 메서드)을 갖고 있다.
또한 추가적으로 hasBasket 프로퍼티를 가진다.
class Tandem: Bicycle {
var currentNumberOfPassengers = 0
}
let tandem = Tandem()
tandem.hasBasket = true
tandem.currentNumberOfPassengers = 2
tandem.currentSpeed = 22.0
print("Tandem: \(tandem.description)")
// Tandem: traveling at 22.0 miles per hour
Tandem 인스턴스를 생성하면, 자신이 가진 새로운 프로퍼티와 상속받은 프로퍼티 모두를 갖게 된다.
Overriding
서브 클래스는 슈퍼 클래스가 상속해준 것이 아니라면 자기 자신이 구현한 인스턴스 메서드, 타입 메서드, 인스턴스 프로퍼티, 타입 프로퍼티, 서브스크립트를 가질 수 있다. 만약 슈퍼클래스에서 상속받은 특성들을 재정의 하고 싶다면 override 키워드를 이용해서 재정의가 가능하다. 스위프트 컴파일러는 override 키워드를 보게 되면 기존에 정의된 것을 재정의하는 것인지 확인하게 된다.
Accessing Superclass Methods, Properties, and Subscripts
슈퍼클래스의 것을 재정의하더라도 여전히 슈퍼클래스의 것을 쓰고 싶을 때가 있다.
이 때, super 키워드를 사용하면 된다.
- 재정의된 메서드 someMethod() 는 슈퍼클래스의 someMethod()를 부르기 위해서 super.someMethod() 를 사용하면 된다.
- 재정의된 프로퍼티 someProperty() 는 슈퍼클래스의 someProperty()를 부르기 위해서 super.someProperty() 를 사용하면 된다.
- 재정의된 서브스크립트 someIndex 는 슈퍼클래스의 같은 서브스크립트를 부르기 위해 super[someIndex] 를 사용하면 된다.
Overriding Methods
상속받은 인스턴스나 타입 메소드를 재정의할 수 있다.
class Train: Vehicle {
override func makeNoise() {
print("Choo Choo")
}
}
let train = Train()
train.makeNoise()
// Prints "Choo Choo"
Overriding Properties
상속받은 인스턴스나 타입 프로퍼티를 재정의해서 프로퍼티에 대한 커스텀 getter와 setter를 제공할 수 있고, 프로퍼티 observer 를 추가해서 재정의하는 프로퍼티가 observe 할 수 있게 한다.
Overriding Property Getters and Setters
상속받은 프로퍼티가 stored 프로퍼티이든 computed 프로퍼티이든 상관 없이, 재정의하는 프로퍼티에 커스텀 getter(setter)를 설정할 수 있다. 상속받을 때, 서브 클래스는 상속받는 프로터티가 store 또는 computed 속성을 갖는지 알 수 없다. 서브 클래스는 오직 이름과 타입만을 알 뿐이다. 따라서 재정의 할 때, 반드시 이름과 타입을 명시해야 한다. 이렇게 하는 이유는 컴파일러가 슈퍼클래스의 프로퍼티에 재정의하게 되는 프로퍼티가 있는지 이름과 타입으로 확인하기 때문이다.
read-only 프로퍼티를 상속받을 때는 getter와 setter를 제공함으로서 read-write 프로퍼티로 재정의 할 수 있다.
그러나 read-write 프로퍼티를 상속 받을 때는 read-only 프로퍼티로 재정의 할 수 없다.
class Car: Vehicle {
var gear = 1
override var description: String {
return super.description + " in gear \(gear)"
}
}
let car = Car()
car.currentSpeed = 25.0
car.gear = 3
print("Car: \(car.description)")
// Car: traveling at 25.0 miles per hour in gear 3
Overriding Property Observers
상속받은 프로퍼티에 프로퍼티 observer 를 추가하기 위해 재정의를 할 수 있다. 이렇게 하면 기존에 프로퍼티가 어떻게 구현되어 있는지와 상관없이 상속받은 프로퍼티의 값이 변할 때 알려주게 된다.
상속받은 constant stored 프로퍼티와 read-only computed 프로퍼티에는 프로퍼티 observer 를 추가할 수 없다!
또한, 하나의 프로퍼티에 setter 와 프로퍼티 observer 를 모두 재정의 하는 것은 불가능하다!
class AutomaticCar: Car {
override var currentSpeed: Double {
didSet {
gear = Int(currentSpeed / 10.0) + 1
}
}
}
let automatic = AutomaticCar()
automatic.currentSpeed = 35.0
print("AutomaticCar: \(automatic.description)")
// AutomaticCar: traveling at 35.0 miles per hour in gear 4
Preventing Overrides
메서드, 프로퍼티, 서브스크립트를 재정의하지 못하게 막으려면 final 키워드를 사용하면 된다.
final var, final func, final class func, final subscript
이렇게 설정해 두면, 서브클래스에서 재정의하려고 할 때 컴파일 에러를 띄우게 된다.
또한 extension 안에서 메서드, 프로퍼티, 서브크립트를 추가한다면 자동으로 final 이 된다.
클래스 전체를 final 로 만들고 싶다면 class 키워드 전에 final 을 붙이면 된다. (final class)
final 클래스를 하위 클래스로 만드려고 하면 컴파일 오류를 띄우게 된다.
'Swift' 카테고리의 다른 글
[Swift] Structure vs Class 무엇을 골라야 할까? (0) | 2022.01.14 |
---|---|
[Swift] Queues & Threads - Concurrency by Tutorials 2편 (0) | 2022.01.13 |
[Swift] Enumerations 에 대해 알아보자 (0) | 2022.01.01 |
[Swift] GCD & Operations - Concurrency by Tutorials 1편 (0) | 2021.12.20 |
[Swift] ARC 에 대해서 알아보자 (0) | 2021.12.16 |