web-dev-qa-db-ja.com

Swiftオーバーロードinit()

Swiftでinitメソッドをオーバーロードします。どうすればそれを実装できますか?

ここで動作しない私のコード

コードが削除されました

編集:

だからそれはうまくいくでしょう

override init() {
    super.init();
}

init(title:String?) {
    super.init();
    self.title = title
}

convenience init(title:String?, imageName:String?) {
    self.init(title:title)
    self.imageName = imageName
}

convenience init(title:String?, imageName:String?, contentKey:String?) {
    self.init(title:title, imageName:imageName)
    self.contentKey = contentKey
}
9
Zeropointer

更新された回答

_class Y { }
class X : Y {
    var title: String?
    var imageName: String?

    convenience override init() {
        self.init(title: nil, imageName: nil)
    }

    convenience init(title:String?) {
        self.init(title: title, imageName: nil)
    }

    init(title: String?, imageName: String?) {
        self.title = title
        self.imageName = imageName
        super.init()
    }
}
_
  • 最も完全な初期化子を指定された初期化子として使用します。

    この場合、init(title: String?, imageName: String?)はすべてのプロパティを設定する唯一の初期化子であるため、指定された初期化子である必要があります。

  • super.init()を呼び出す前にプロパティを初期化します。

    私の古い答えは、titleimageNameが両方ともvarであり、オプションであったためにのみ機能しました。

    Swiftプログラミング言語:初期化 の2フェーズ初期化セクション

    安全チェック1

    指定された初期化子は、スーパークラス初期化子に委任する前に、そのクラスによって導入されたすべてのプロパティが初期化されていることを確認する必要があります。


古い回答

サンプルを遊び場に接続しました。これがどのように機能するかを示しています。

_class Y { }
class X : Y {
    var title: String?
    var imageName: String?

    override init() {

    }

    init(aTitle:String?) {
        super.init()
        self.title = aTitle
    }

    convenience init(aTitle:String?, aImageName:String?) {
        self.init(aTitle: aTitle)
        self.imageName = aImageName
    }
}
_
  • init(aTitle:String?, aImageName:String?)init(aTitle:)を呼び出すことができず、指定された初期化子であるため、便利な初期化子である必要があります。
  • _self.init_は、init(aTitle:String?, aImageName:String?)の何よりも前にある必要があります。
  • イニシャライザにはパラメータ名を渡す必要がありますself.init(aTitle)self.init(aTitle: aTitle)である必要があります。

ちなみに、スタイル上の理由から、不要なセミコロンを削除し、super.init()を最初に配置しました。

お役に立てば幸いです。


[〜#〜]更新[〜#〜]

Appleのアドバイスに従うには、指定されたのは1つだけで、残りは便利な初期化子である必要があります。たとえば、init(aTitle:String?)を指定された初期化子にする場合、コードは次のようになります。

_convenience override init() {
    self.init(aTitle: nil) // A convenience initializer calls the designated initializer.
}

init(aTitle:String?) {
    super.init() // Only the designated initializer calls super.init.
    self.title = aTitle
}

convenience init(aTitle:String?, aImageName:String?) {
    self.init(aTitle: aTitle)  // A convenience initializer calls the designated initializer.
    self.imageName = aImageName
}
_

UIViewのように、複数回指定された初期化子が必要になる場合がありますが、それは例外であり、ルールではありません。


UPDATE 2

クラスには、指定された初期化子が1つ必要です。コンビニエンス初期化子は、(最終的に)指定された初期化子を呼び出します。

初期化

クラスには複数の初期化子が含まれる場合があります。これは、初期化データがさまざまな形式をとることができる場合、または特定の初期化子が便宜上デフォルト値を提供する場合に発生します。この場合、初期化メソッドの1つは、指定された初期化子と呼ばれ、初期化パラメーターの完全な補完を取ります。

複数の初期化子

指定初期化子

初期化パラメーターの完全な補完をとるクラスの初期化子は、通常、指定された初期化子です。サブクラスの指定された初期化子は、スーパークラスにメッセージを送信して、そのスーパークラスの指定された初期化子を呼び出す必要があります。 便利な(またはセカンダリ)初期化子(initを含めることができます)はsuperを呼び出しません。代わりに、(自己へのメッセージを介して)初期化子を次に多くのパラメーターを持つシリーズで、渡されなかったパラメーターのデフォルト値を提供します。 このシリーズの最後の初期化子は、指定された初期化子です。

17
Jeffery Thomas