ぜのぜ

しりとりしようぜのぜのぜのぜ

49日目 Automatic Initializer Inheritance

日記

窓開ければ結構涼しいと思ったがやっぱ無理.これこそ在宅勤務手当の使い所.

初めて知ったこと

Automatic Initializer Inheritance

スーパークラスのイニシャライザの継承に関するルール

  1. サブクラスで一つもDesignated Initializerを定義しなければ,自動的にスーパークラスの全てのDesignated Initializerを継承する
  2. ルール1による継承もしくは,クラス定義の一部としての独自実装によってスーパークラスの全てのDesignated Initializerを実装していれば,自動的にスーパークラスの全てのConvenience Initializerを継承する

Rule 1

If your subclass doesn’t define any designated initializers, it automatically inherits all of its superclass designated initializers.

Rule 2

If your subclass provides an implementation of all of its superclass designated initializers—either by inheriting them as per rule 1, or by providing a custom implementation as part of its definition—then it automatically inherits all of the superclass convenience initializers.

スーパークラスのDesignated Initializerが継承されないパターン

ルール2によってConvenience Initializerも継承されない

class Sup {
    let str: String

    init(_ str: String) {
        self.str = str
    }

    convenience init(isHoge: Bool) {
        self.init(isHoge ? "hoge" : "")
    }
}

class Sub: Sup {
    init() {
        super.init("str")
    }
}

// Argument passed to call that takes no arguments
// print(Sub("str").str)
// Argument passed to call that takes no arguments
// print(Sub(isHoge: true).str)

スーパークラスのDesignated Initializerを継承することによってConvenience Initializerも継承するパターン

class Sup {
    let str: String

    init(_ str: String) {
        self.str = str
    }

    convenience init(isHoge: Bool) {
        self.init(isHoge ? "hoge" : "")
    }
}

class Sub: Sup {}

print(Sub("str").str) // str
print(Sub(isHoge: true).str) // hoge

独自実装によってConvenience Initializerも継承するパターン

class Sup {
    let str: String

    init(_ str: String) {
        self.str = str
    }

    convenience init(isHoge: Bool) {
        self.init(isHoge ? "hoge" : "")
    }
}

class Sub: Sup {
    override init(_ str: String) {
        super.init(str.uppercased())
    }
}

print(Sub("str").str) // str
print(Sub(isHoge: true).str) // hoge

スーパークラスのDesignated Initializerを全て実装せずにConvenience Initializerを継承することができないのは,Convenience Initializerは必ずそのクラスのDesignated Initializerを呼ばないといけないという決まりがあるからだと思う.(スーパークラスのDesignated Initializerを呼ぶConvenience Initializerを定義できない.

A convenience initializer must call another initializer from the same class. Initializer Delegation for Class Types