web-dev-qa-db-ja.com

便利な初期化オーバーライド

問題

Overrideサブクラスの便利な初期化子であり、コンパイルエラーが発生します。

詳細

Swift(v4.1)で便利な初期化子をオーバーライドできない理由を理解するのに問題があります。ドキュメントを読むと、次の2つのルールが私の質問に当てはまることがわかりました。

ルール1サブクラスが指定された初期化子を定義していない場合、サブクラスはそのスーパークラスの指定された初期化子をすべて自動的に継承します。

ルール2サブクラスがスーパークラスで指定されたすべてのイニシャライザーの実装を提供する場合(ルール1に従ってそれらを継承するか、定義の一部としてカスタム実装を提供することにより)、サブクラスはすべてのスーパークラスコンビニエンスイニシャライザーを自動的に継承します。

以下のコードでは、私は最初のルールに該当し、すべての便利な初期化子はClassBに継承されます。さらに、ルール1に従って、指定されたすべての初期化子を継承したため、すべての便利な初期化子も継承されます。

_class ClassA<T> {

    // This array would be private and not visible from ClassB
    var array: [T]?

    init() { }

    convenience init(array: [T]) {
        self.init()

        self.array = array
    }
}

class ClassB<T>: ClassA<T> {

    var anotherArray: [T]?

    // I feel like I should include the "override" keyword
    // but I get a compiler error when "override" is added before "convenience init".
    convenience init(array: [T]) {
        self.init()

        self.anotherArray = array
    }
}

// Works fine
let instanceA = ClassA(array: [1, 2])
// Compile error when override is added:
// error: Initializer does not override a designated initializer from its superclass
// note: attempt to override convenience initializer here
//     convenience init(array: [T]) {
//                 ^
let instanceB = ClassB(array: [1, 2])
_

しかし、私が理解していないことは次のとおりです。ClassBの実装はinit(array:)と少し異なり、その便利な初期化子をオーバーライドしたいと思います。 overrideキーワードを使用すると、コンパイルエラーが発生します。これらの初期化の概念を間違って理解していますか?

18
Jad

理由overrideは不要です

逆に、スーパークラスconvenience初期化子と一致するサブクラス初期化子を作成する場合、ルールに従って、そのスーパークラスコンビニエンス初期化子をサブクラスから直接呼び出すことはできません。上記のイニシャライザチェーンで説明されています。したがって、サブクラスは(厳密に言えば)スーパークラス初期化子のオーバーライドを提供していません。その結果、スーパークラスのコンビニエンスイニシャライザーの一致する実装を提供するときに、override修飾子を記述しません。

しかし、書かれているように、それはうまくいくはずです—私が知る限り、これはコンパイラのバグです。 ClassBの初期化子のarray引数の名前を次のように変更した場合。 array2、それからそれは期待通りに動作します。あなたは レーダーを提出する

18
jtbandes