web-dev-qa-db-ja.com

Swiftサブクラス-Init()をオーバーライドする方法

Initメソッドを使用した次のクラスがあります。

_class user {
  var name:String
  var address:String

  init(nm: String, ad: String) {
    name = nm
    address = ad
  }
}
_

このクラスをサブクラス化しようとしていますが、super.init()部分でエラーが発生し続けます。

_class registeredUser : user {
     var numberPriorVisits: Int

     // This is where things start to go wrong - as soon as I type 'init' it 
     // wants to autocomplete it for me with all of the superclass' arguments, 
     // and I'm not sure if those should go in there or not:
     init(nm: String, ad: String) {  
        // And here I get errors:
        super.init(nm: String, ad: String) 

     // etc....
_

AppleのiBookにはサブクラス化の例がありますが、実際の引数を含むinit()メソッドを持つフィーチャクラスはありません。すべてのinitには引数がありません。

だから、これをどうやってやるの?

41
sirab333

Chuckの答えに加えて、super.initを呼び出す前に、新しく導入されたプロパティを初期化する必要もあります

指定された初期化子は、スーパークラス初期化子に委任する前に、クラスによって導入されたすべてのプロパティが初期化されていることを確認する必要があります。 (Swiftプログラミング言語->言語ガイド->初期化)

したがって、機能させるには:

init(nm: String, ad: String) {
    numberPriorVisits = 0  
    super.init(nm: nm, ad: ad) 
}

この単純なゼロへの初期化は、プロパティのデフォルト値もゼロに設定することで実行できます。また、そうすることをお勧めします。

var numberPriorVisits: Int = 0

このようなデフォルト値が必要ない場合は、初期化子を拡張して、新しいプロパティの新しい値も設定するのが理にかなっています。

init(name: String, ads: String, numberPriorVisits: Int) {
    self.numberPriorVisits = numberPriorVisits
    super.init(nm: name, ad: ads)
}
36
Jens Wirth

Swift 2.0以降では、このように動作します(すべての場合)

init(newString:String) {
    super.init(string:newString)
    // Designed initialiser 
}
override init(someString: String) {
    super.init(mainString: someString)
    // Override initialiser when subclass some class 
}
required init?(coder aDecoder: NSCoder) {
    fatalError("init(coder:) has not been implemented")
    // Some boilerplate code to handle error (needed when override)
}
convenience init(newString:String, withParameters:Dictionary<String,String>) {
    self.init(someString:newString)
    //Convenience initialiser 
}
11
Roman Safin

通常のメソッドに引数を渡すのと同じように、引数を初期化子に渡します。

init(nm: String, ad: String) {  
    super.init(nm: nm, ad: ad) 
}

参考のために、これはSwift Language Guide。の Designated and Convenience Initializers In Action )セクションに示されています。

3
Chuck

値をnumberPriorVisitsに設定し、呼び出しのタイプをsuperに変更しようとしましたか?

class user {
    var name:String
    var address:String

    init(nm: String, ad: String) {
        name = nm
        address = ad
    }
}


class registeredUser : user {
    var numberPriorVisits: Int;

    init(nm: String, ad: String) {
        self.numberPriorVisits = 0;
        super.init(nm: nm, ad: ad)
    }
}
1
Peter Witham