→ 클래스만 상속이 가능하며 단일 상속만 가능하다!
→ 기본 클래스를 기반으로 새로운 클래스를 만드는 작업이다.
상속 받는 클래스 → 서브 클래스
상속 해주는 클래스 → 슈퍼 클래스
예를 통하여 이해해보자. 아래와 같이 Human
클래스가 존재한다.
class Human: Hashable {
var name: String?
var age: Int?
}
그리고, Human
클래스를 상속 받는 Teacher
클래스가 존재한다. Teacher
클래스는 Human
클래스의 멤버들을 모두 가지면서, 추가적으로 더 필요한 멤버들을 가진 클래스이다.
class Teacher: **Human** {
var subject: String?
}
“Teacher이 Human이란 클래스를 상속 받는 것” ⇒ 서브클래싱
‼️ 그런데 만약, 상속을 금지하고 싶다면? ⇒ final
을 붙혀준다
. final을 붙혀준다고해서 서브 클래스에서 접근을 못하는 것은 아니다!
→ 서브 클래스는 슈퍼 클래스의 서브 스크립트, 타입 프로퍼티, 인스턴스 프로퍼티, 타입 메서드, 인스턴스 메서드등을 구현할 수 있는데, 이걸 오버라이딩이라고 한다.
→ override
(재정의)라는 키워드를 통하여 구현한다.
아래의 예를 통하여 한번 이해해보자.
class Human {
func description() {
print("나는 사람입니다")
}
}
class Teacher: Human {
override func description() {
print("나는 선생입니다")
}
}
let miro: Teacher = .init()
miro.description() // "나는 선생입니다"
‼️ 단, 여기서 조심해야될 점은 오버라이딩을 한 경우, Super Class의 메소드를 이미 재정의 해버렸기에 더 이상의 Super Class의 메소드(description())은 실행되지 않는다.
🤔 그렇다면, super class의 메소드도 실행하고, sub class의 메소드도 실행하고 싶다면 어떻게 해야될까?
→ super
를 사용하자!
아래와 같이 서브 클래스에서 오버라이딩을 진행할 때에 슈퍼 클래스의 메소드를 직접 실행해주면 된다.
class Teacher: Human {
override func description() {
super.description()
print("나는 선생입니다")
}
}
let miro: Teacher = .init()
miro.description()
// 나는 사람입니다.
// 나는 선생입니다.
→ 상속 받은 프로퍼티 값의 변경을 추적할 프로퍼티 옵저버
를 추가하거나, 상속 받은 프로퍼티를 오버라이딩을 통하여 해당 속성에 대한 getter
, setter
를 제공한다.(연산 속성
)
→ 프로퍼티 이름
/ 타입
을 꼭 명시해주자!
저장
프로퍼티의 오버라이딩?..저장
프로퍼티를 오버라이딩을 할 수는 없을까? → 할 수 없다.
class Human {
var name = "Miro"
}
class Teacher: Human {
override var name: String = "Miro2"// Cannot override with a stored property 'name'
}
그런데, 만약 연산 속성으로 오버라이딩을 한다면?(즉, getter, setter를 모두 구현해주면) → 가능하다!!
class Human {
var name = "Miro"
}
class Teacher: Human {
var alias = "Miro찾기"
override var name: String {
get {
return self.alias
}
set {
self.alias = newValue
}
}
}
연산
프로퍼티의 오버라이딩‼️규칙
즉, SubClass는 SuperClass 보다 더 할 수는 있지만, 덜 하면 안된다!!
예를 통하여 이해해보자. case 1
class Human {
var name = "Sodeul"
var alias: String {
return self.name + " 바보"
}
}
// get만 구현
class Teacher: Human {
override var alias: String {
return self.name + " 멍청이"
}
}
// get,set 둘 다 구현
class Teacher: Human {
override var alias: String {
get {
return self.name + " 멍청이"
}
set {
self.name = newValue
}
}
}
case 2
class Human {
var name = "Sodeul"
var alias: String {
get {
return self.name + " 바보"
}
set {
self.name = newValue
}
}
}
// **ERROR**
class Teacher: Human {
override var alias: String { // Cannot override mutable property with read-only property 'alias'
return self.name + " 멍청이"
}
}
저장
프로퍼티 → var로 선언된 프로퍼티만 옵저버를 추가할 수 있다.연산
프로퍼티 → getter/setter 모두 구현된 프로퍼티만 옵저버를 추가할 수 있다.저장
프로퍼티의 경우
class Human {
var name = "Miro"
}
class Teacher: Human {
override var name: String {
willSet {
print("name 값 변경 된다!!! \(newValue)")
}
didSet {
print("name 값 변경 됐다!!! \(oldValue)")
}
}
}
let teacher: Teacher = .init()
teacher.name = "Unknown"
// name 값이 변경된다!!! Unknown
// name 값이 변경 됐다!!! Miro