티스토리 뷰
클래스는 메소드, 프로퍼티 그리고 다른 특성들을 다른 클래스로부터 상속 받을 수 있습니다. 한 클래스가 다른 클래스를 상속받을 때, 상속 받은 클래스는 subclass 라고 불리며, 상속해준 클래스를 superclass 라고 합니다. 상속은 스위프트의 다른 타입들과 클래스를 구별지는 기본적인 기능입니다.
스위프트의 클래스는 superclass의 메소드, 프로퍼티 그리고 서브스크립트에 접근 및 호출이 가능하며, 또한 자신만의 오버로딩된 버전 또한 수정 및 재정의가 가능합니다. 클래스는 또한 값이 변경되었을 때 알림을 받기 위해서 상속된 프로퍼티에 프로퍼티 옵저버를 추가할 수 있습니다. 원본 프토퍼티가 저장, 연산.프로퍼티로 정의되었음에도 불구하고 말이죠.
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()
상속받기
다른 클래스를 상속하는 것은 기존에 있던 클래스의 특성을 이어받고 그것을 수정할 수 있음을 뜻합니다. 다른 클래스를 상속 받기 위해선 새로운 클래스를 선언할 때 subclass 이름 뒤에 :를 붙이고 상속해줄 클래스의 이름을 적어주면 됩니다.
class SomeSubclass: SomeSuperclass {
// subclass definition goes here
}
아까 base 클래스를 설명할 때 예제를 가져와서 설명하면 기존에 있던 Vehicle 클래스를 상속 받은 BIcycle 클래스는 Vehicle 클래스에 있는 makeNoise 메소드를 사용할 수 있을 뿐만 아니라 Vehicle 클래스에만 필요한 hasBasket 프로퍼티를 추가하여 사용할 수 있습니다.
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
클래스는 서브클래스를 또다시 상속가능합니다. 상속받는 클래스가 어떤 서브, 베이스, 슈퍼 클래스 중 어느 상태이건 간에 문제없이 상속받을 수 있음을 의미합니다. Tandem 클래스는 Vehicle의 서브클래스였던 Bicycle을 또 다시 상속받았습니다.
class Tandem: Bicycle {
var currentNumberOfPassengers = 0
}
오버라이딩
서브클래스는 슈퍼클래스로부터 상속받은 인스턴스 메소드, 타입 메소드. 인스턴스 프로퍼티, 타입 프로퍼티, 서브스크립트를 자기만의 것으로 커스텀해서 사용할 수 있습니다. 이를 overriding(오버라이딩) 한다고 합니다. 오버라이딩 하기 위해서는 override 키워드를 앞에 붙여줘야합니다.
슈퍼클래스의 메소드, 프로퍼티. 서브스크립트에 접근하기
오버라이딩된 특성들을 사용하지 않고 슈퍼클래스의 것을 사용하고 싶을 때가 있습니다. 이럴때는 super 키워드를 앞에 붙여 사용하면 됩니다. 이를태면 super.someMethod(), super.someProperty, super[someIndex] 같이 말이죠
메소드 오버라이딩 하기
앞에 사용했던 Vehicle 클래스를 이어 가져와서 설명하면, Train 서브클래스를 만들고 ovveride 키워드를 선행하여 붙여줘서 기존에 있던 makeNoise() 메소드를 오버라이딩 시켜서 커스텀해서 사용하고 있습니다.
class Train: Vehicle {
override func makeNoise() {
print("Choo Choo")
}
}
let train = Train()
train.makeNoise()
// Prints "Choo Choo"
프로퍼티 오버라이딩 하기
메소드와 동일하게 프로퍼티 앞에 ovveride 키워드를 붙여주면 됩니다. 오버라이딩 할 때는 이름과 타입을 전부 작성해줘야 하며 읽기용 프로퍼티도 오버라이딩해서 쓰기도 가능하게 만들 수 있으나, 읽기/쓰기 전부 가능한 프로퍼티를 오버라이딩해서 읽기만 가능하게 만들 수는 없습니다.
class Car: Vehicle {
var gear = 1
override var description: String {
return super.description + " in gear \(gear)"
}
}
프로퍼티 옵서버 오버라이딩 하기
상속받은 프로퍼티에 프로퍼티 옵서버를 추가하기 위하여 오버라이딩해서 사용할 수 있습니다. 이를 통해 상속받은 값이 변경되었을 때 알림을 받을 수 있습니다. 그러나 상속받은 상수 저장 프로퍼티 혹은 상속받은 읽기 전용 연산 프로퍼티에는 당연하게도 추가 할 수 없습니다. 또한 같은 프로퍼티에 프로퍼티 옵서버를 붙여놓고 setter를 사용할 수 없습니다. 앞서 프로퍼티 챕터에서 설명한대로 역할이 겹치기 때문입니다.
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
오버라이딩 방지하기
오버라이딩을 막기 위해서 특성 앞에 final 연산자를 붙일 수 있습니다. 클래스 선언부 자체 final을 붙여서 아예 해당 클래스안의 모든 특성이 오버라이딩 되는 것을 막을 수 있습니다.
-> 여기서 예전에 타입 메소드. 프로퍼티를 선언할 때 오버라이딩을 허용하느냐에 따라 static, class 키워드를 붙인다~ 라고 배웠는데 final 연산자를 중복되는 기능이 있길래 확인해보니, class 키워드로 선언한 타입 프로퍼티, 메소드이더라도 final을 붙이면 즉, final class 타입 프로퍼티, 메소드이면 오버라이딩이 불가능하다고 한다..
'Swift Language Guide' 카테고리의 다른 글
Error Handling(에러 핸들링) (0) | 2020.11.19 |
---|---|
Optional Chaining(옵셔널 체이닝) (0) | 2020.11.18 |
10. 서브스크립트 (0) | 2020.11.08 |
9. 메소드 (0) | 2020.11.06 |
8. 프로퍼티 (0) | 2020.11.03 |