본문 바로가기
Swift

8. 상속

by 루에 2015. 10. 5.
반응형

상속과 초기화 메소드


상속했을 경우 부모 클래스와 자식 클래스에서 초기화 메소드가 동작하는 모습으로 두 종류의 초기화 방식이 다른다. 쉽게 표현하자면 Designated는 위(super)로 위임하도록 작성하고 Convenience는 옆(other Convenience or Designated)으로 위임하도록 작성한다.



초기화 메소드 상속


초기화 메소드는 자식 클래스에 제한된 경우에만 상속된다. 상속되는 첫 번째 조건은 자식 클래스에 Designated Initializer가 없는 경우다. 클래스에 그것이 없다는 것은 별도의 초기화가 필요한 프로퍼티를 선언하지 않았다는 것이다. 자식 클래스에 Convenience Initializer를 작성해도 초기화 상속이 발생한다. 자식 클래스의 객체를 생성하려면 부모 클래스에서 상속받은 초기화 메소드를 이용한다.

class Parent {

    var a : Int

    

    init(a: Int) {

        self.a = a

    }

    

    convenience init() {

        self.init(a: 0)

    }

}


// 별도의 초기화가 필요한 프로퍼티가 없는 자식 클래스

class Child1 : Parent {

    var b = 100

}


// 부모 클래스에서 상속받은 Designated 자식 클래스 객체 생성

var child1 = Child1(a: 10)


// 부모 클래스에서 상속받은 Convenience 자식 클래스 객체 생성

var child2 = Child1()



초기화 메소드 재정의


초기화 메소드도 일반 메소드처럼 재정의가 가능하다. 마찬가지로 override를 붙여서 사용한다.



Required Initializer


자식클래스에서 부모클래스의 초기화 메소드를 반드시 재정의하도록 하기 위한 지시자 required가 있다. 이 것이 붙은 모든 초기화 메소드를 재정의해야 한다. 이 경우 override를 생략한다.

class Parent2 {

    var a : Int

    

    required init(a: Int) {

        self.a = a

    }

    

    init(b: Int) {

        self.a = b

    }

    

    required convenience init() {

        self.init(a: 0)

    }

}


class Child3 : Parent2 {

    var c : Int

    

    // required 초기화 메소드 재정의

    required init(a: Int) {

        self.c = 0

        

        super.init(a: a)

    }

    

    required convenience init() {

        self.init(a: 0) // 재정의한 required 초기화 메소드 호출

    }

}


class AnotherChild : Parent2 {

    // 자식 클래스에서 정의할 프로퍼티가 없고, Designated Initializer 없으므로 부모의 초기화 메소드를 모두 상속, 경우 required 재정의하지 않는다.

}



Failable Initializer



클래스 상속에서도 failable initializer를 고려해야 한다. 부모 클래스의 failable initializer로 위임하는 자식 클래스도 똑같이 failable로 작성해야 한다. 초기화 조건 검사 코드는 부모 클래스의 초기화 메소드 위임을 마친 이후에 작성한다.




초기화 메소드 정리


애플에서는 초기화 메소드를 편하게 작성하기 위한 몇 가지 규칙과 팁을 제공한다.


다음은 초기화 메소드 위임에 관련된 규칙이다.


Designated Initializer는 부모 클래스의 Designated Initializer를 호출한다.

Convenience Initializer는 같은 클래스의 다른 초기화 메소드를 호출한다.

Convenience Initializer는 초기화 메소드 위임을 따라 Designated Initializer을 호출한다.










반응형

댓글