[Swift] - 상속(inheritance)

longlivedrgn·2023년 1월 8일
0

swift문법

목록 보기
22/36
post-thumbnail

상속(Inheriatance)

→ 클래스만 상속이 가능하며 단일 상속만 가능하다!

서브 클래싱(subclassing)

→ 기본 클래스를 기반으로 새로운 클래스를 만드는 작업이다.

상속 받는 클래스 → 서브 클래스

상속 해주는 클래스 → 슈퍼 클래스

예를 통하여 이해해보자. 아래와 같이 Human 클래스가 존재한다.

class Human: Hashable {
    var name: String?
    var age: Int?
}

그리고, Human 클래스를 상속 받는 Teacher 클래스가 존재한다. Teacher 클래스는 Human 클래스의 멤버들을 모두 가지면서, 추가적으로 더 필요한 멤버들을 가진 클래스이다.

class Teacher: **Human** {
    var subject: String?
}

TeacherHuman이란 클래스를 상속 받는 것” ⇒ 서브클래싱

  • Human → 슈퍼 클래스
  • Teacher → 서브 클래스

‼️ 그런데 만약, 상속을 금지하고 싶다면? ⇒ final 을 붙혀준다

. final을 붙혀준다고해서 서브 클래스에서 접근을 못하는 것은 아니다!

오버라이딩(Overriding)

→ 서브 클래스는 슈퍼 클래스의 서브 스크립트, 타입 프로퍼티, 인스턴스 프로퍼티, 타입 메서드, 인스턴스 메서드등을 구현할 수 있는데, 이걸 오버라이딩이라고 한다.

override (재정의)라는 키워드를 통하여 구현한다.

메소드 오버라이딩(Method Overriding)

아래의 예를 통하여 한번 이해해보자.

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()
// 나는 사람입니다.
// 나는 선생입니다.

프로퍼티 오버라이딩(Method Overriding)

→ 상속 받은 프로퍼티 값의 변경을 추적할 프로퍼티 옵저버를 추가하거나, 상속 받은 프로퍼티를 오버라이딩을 통하여 해당 속성에 대한 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
        }
    }
}
  • 연산 프로퍼티의 오버라이딩

‼️규칙

  • case 1) SuperClass가 get만 구현했다. → SubClass는 get만 구현 OR get,set 둘 다 구현 가능하다
  • case 2)SuperClass가 get, set 둘 다 구현했다. → SubClass는 무조건 get, set 둘 다 구현해야된다.

즉, 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

📚참고자료

Swift) 상속(Inheritance) 정복하기 (2/2) - 오버라이딩(Overriding)

0개의 댓글