ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Swift #10 - 상속
    Swift의 온도 2021. 1. 15. 03:05

     

    1. 클래스 상속과 재정의

     

    - 상속

    #클래스 상속

     *상속으로 새로운(자식) 클래스 정의

     *기존(부모) 클래스 프로퍼티/메소드 상속

     

    #Swift의 클래스 상속

     *단일 상속

     *상속을 하는 클래스 문법

    class CLASS_NAME : SUPER_CLASS {
    }
    cs
    *부모 클래스
     
    class Parent {
        var value = 0
        func hello() {}
    }
     
    *자식 클래스
     
    class Child : Parent {}
     
    *자식 클래스의 객체에서 부모의 프로퍼티, 메소드 사용
     
    var obj = Child()
    obj.value = 1999
    obj.hello()
    cs

     

    - 재정의

    #메소드 재정의(override)

    *부모 클래스에 정의된 메소드 재정의
    *같은 이름. 다른 동작
     
    override func hello() {}
    cs
    *사각형의 넓이 구하기 재정의
     
    class Rectangle {
        var width = 0
        var height = 0
        func size() -> Int {
            return width * height
        }
    }
    class Square : Rectangle {
        override func size() -> Int {
            return width * width
        }
    }
    cs

     

     

    #계산 프로퍼티 재정의

    *get/set 행위 재정의
     
    class Rectangle {
        var width = 0
        var height = 0
        var isSquare : Bool
            get { return width == height }
        }
    }
    class Square : Rectangle {
        override var isSquare : Bool {
            get { return true }
        }
    }
    cs

     

     

    - 프로퍼티 재정의

    #저장 프로퍼티 재정의

    *didSet, willSet은 추가
     
    class Square : Rectangle {
        override var width : Int {
            didSet(newValue) {
                // 새로 추가되는 행위
            }
        }
    }
    cs

     

    - 주의

    #재정의시 주의사항

     *override 누락하면 에러

     *재사용이 아닌데 override 사용하면 에러

     *final : override 금지 (클래스, 프로퍼티, 메소드)

     

    - 포인터 super

    #부모 클래스 참조

     *super : 부모 클래스를 참조하는 포인터

     *재정의시 부모 클래스 구현 참조

     *부모 클래스로 Initializer Delegation

     

    - 재사용과 super

    #재사용과 self, super

    class Parent {
        func description() -> String {
            return "부모 클래스"
        }
    }
    class Child : Parent {
        override func description() -> String {
            return "자식 클래스"
        }
     
        func printDescription() {
            print("super.description : \(super.description())")
            print(self.description : \(self.description())")
        }
    }
    cs

     

    2. 클래스 상속과 Initializer

     

    - 상속과 초기화

    #상속과 프로퍼티

     *부모 클래스의 프로퍼티 상속

     *초기화가 필요한 프로퍼티 -> Initializer

     *자식 클래스의 초기화 + 부모 클래스의 초기화

     

    #Initializer의 상속

     *클래스 상속 -> 메소드 상속

     *Initializer도 상속하는가/

     *상속에서의 Initializer Delegation은?

     *제한된 조건에서만 상속

     

    - Initializer 상속

    #Initializer 상속하는 경우

     

    #자식 클래스에 Designated Initializer 없는 경우

     *별도의 초기화가 필요한 프로퍼티가 없음

     *부모 클래스의 Designated Initializer 상속

     

    #자식 클래스에서 모든 Designated Initializer를 재정의

     *convenience Initializer 상속

     

    #Designated Initializer를 작성하지 않는 경우

    *클래스 정의와 상속
     
    class Parent {
        var a : Int
        init(a : Int) {
            self.a = a
        }
        convenience init() {
            self.init(a : 0)
        }
    }
    class Child : Parent {}
     
    *객체 생성
     
    var childObj1 = Child(a : 10)
    var childObj2 = Child()
    cs

     

    - 자식 클래스의 Initializer

    #자식 클래스의 Designated Initializer

    init(파라미터) {
        //자식 클래스의 프로퍼티 초기화
        //부모 클래스의 Designated Initializer 위임
        //나머지 초기화 동작
    }
     
    *자식 클래스에 Designated Initializer를 작성하면 - Initializer 상속 안 함
    cs
    class Parent {
        var a : Int
        init(a : Int) { self.a = 0 }
    }
    class Child : Parent {
        var b : Int
        init(a : Int, b : Int) {
            self.b = b
            super.init(a : a)
        }
    }
     
    *객체 생성
     
    var obj = Child(a : 10, b : 20)
    cs

     

    #자식 클래스의 Convenience Initializer

    convenience(파라미터) {
        //같은 클래스의 Initializer Delegation
        //초기화 코드
    }
    cs

    #Initializer Delegation

     *Initializer Delegation시 Initializer 상속하는가?

     *부모 클래스의 Delegation Initializer를 상속하는 경우

     *부모 클래스의 Delegation Initializer를 상속하지 않는 경우

     

    #자식 클래스의 Convenience Initializer 작성

    *Initializer 상속 안 함
     
    class Child : Parent {
        var b : Int
        init(a : Int, b : Int) {
            self.b = b
            super.init(a : a)
        }
        convenience init(b : init) {
            self.init(a : 10, b : b)
            //나머지 초기화 동작
        }
    }
     
    *객체 생성
     
    var obj = Child(a : 10, b : 20)
    var obj2 = Child(b : 30)
     
    *부모 클래스의 Designated Initializer 상속하는 경우
     
    class Parent {
        var a : Int
        init(a : Int) {
            self.a = a
        }
    }
    class Child : Parent {
        var b = 0
        convenience init(b : Int) {
            self.init(a : 0)
            self.b = b
        }
    }
    cs

     

    - Initializer 재정의

    class Parnet {
        var a : Int
        init(a : Int) {
            self.a = a
        }
    }
    class Child : Parent {
        var b = 0
        override init(a : Int) {
            self.b = 0
            super.init(a : a)
        }
    }
    cs

     

    - Initializer 상속

     *자식 클래스에서 모든 Designated Initializer 재정의

     *Convenience Initializer 상속

     

    - Initializer 재정의

    #모든 Designated Initializer 재정의

    class Parent {
        var a : Int
        init(a : Int) {
            self.a = a
        }
        convenience init() {
            self.init(a : 10)
        }
    }
    class Child : Parent {
        var b : Int
        override init(a : Int) {
            b = 10
            super.init(a : a)
        }
    }
    var child = Child()
    cs

     

    #2단계 초기화(Two-Phase Initializer)

     *1단계 : 자식 클래스에서 부모 클래스로 위임 - 1차 준비

     *2단계 : 추가 초기화 동작(부모 클래스의 내용 커스터마이징)

    class Parent {
        var a : Int
        init() {
            a = 0
        }
    }
    class Child : Parent {
        var b : Int
        init(a : Int, b : Int) {
            self.b = b
            super.init()
     
            self.a = a
        }
    }
    cs

     

    - Required Initializer

    required init() {
    }
    cs

     

    #required Initializer 작성

     *작성 안하면 컴파일 에러

     *required 키워드 사용

     *override 키워드 생략

     *convenience 키워드는 유지

     

    3. 클래스 상속과 Failable Initializer

    #부모 클래스의 Initializer의 위임

     *부모 클래스의 Failable Initializer로 위임 -> Failable Initializer로 작성

     

    #Failable Initializer 재정의

     *Failable Initializer를 Failable Initializer로 재정의

     *Failable Initializer를 non-Failable Initializer로 재정의

     

    - Failable Initializer

    #Failable Initializer가 있는 부모 클래스

    class Parent {
        var value = 0
        init?(value : Int) {
            if value < 0 {
                return nil
            }
        }
        init() {
        }
    }
    cs

     

    'Swift의 온도' 카테고리의 다른 글

    Swift #12 - 구조체와 Enum  (0) 2021.01.20
    Swift #11 - 메모리 관리  (0) 2021.01.19
    Swift #9 - 객체 초기화  (0) 2021.01.14
    Swift #8 - 클래스  (0) 2021.01.13
    Swift #7 - 함수  (0) 2021.01.12

    댓글