2017-01-22 4 views
1

すべてのスーパークラスから継承する一連のクラスがあります。このスーパークラスは、すべてのサブクラスに適したジェネリックな初期化子を提供します。サブクラスでupdateValues()をオーバーライドする自動イニシャライザの継承ルールを回避するSwift

init(values: [String: Any]) { 
    updateValues(dict: values) 
} 

func updateValues(dict: [String: Any]){ 
    //To be implemented in subclasses 
} 

を、各サブクラスが正常に独自の変数を設定することを確実にするために動的ディスパッチを利用することにより、すべてが動作しているようです。具体的には、含まれています。例えば

は、ユーザークラスでは、プロパティがそうのように宣言されています。これは完璧に動作

override func updateValues(dict: [String: Any]) { 
    self.name = dict["name"] as? String 
    self.uid = dict["uid"] as? String 
    self.email = dict["email"] as? String 
    self.username = dict["username"] as? String 
} 

:よう

var name: String? 
var uid: String? 
var email: String? 
var username: String? 

とそのupdateValues()が見えます。しかし、辞書からではなく、変数を手動で設定する必要がある場合は、カスタム指定された初期化子をサブクラスに追加する必要があります。例えば、上述したユーザ・クラスのための1つのそのような初期化は次のようになります

init(name: String?, uid: String?, email: String?, username: String?){... 

しかし、この初期化宣言が望ましくない結果を生じます。 ページのSwift "Automatic Initializer Inheritance"の規則に従って、指定された初期化子がサブクラスに提供されると、スーパークラスの初期化子を継承しなくなります。これで継承は非常に面倒です。自動的に継承したいイニシャライザをオーバーライドする必要があります。すべてのサブクラスに対してsuper.init()を呼び出すだけです。このoverride init - super.init()のすべてのインスタンスのコメントを書き直す必要があります。

まだスーパークラス指定のイニシャライザを継承することはできますか?あるいは私はこれについて間違って考えていますか?

注:サブクラスの指定された初期化子をコメントアウトし、スーパークラス初期化子が自動的に継承されました。サブクラスのイニシャライザを追加する(またはコメントを解除する)ことで、機能の変更は実際にはありません。そのため、スウィフトの強制チェックを回避する方法を探したいと思います。

答えて

1

常に、指定された初期化子を呼び出す必要があります。これが、指定された初期化子であることを意味します。指定された初期化子がinit(value:)の場合、それを呼び出す便利な初期化子はinit(name: String?, uid: String?, email: String?, username: String?)です。新しい「必須呼出し」(すなわち、指定された初期化子)を実装することは、スーパークラスの指定初期化子がこのサブクラスに対して無効であることを意味するが、ここではそうではない。したがって、次のように書いてください:

convenience init(name: String?, uid: String?, email: String?, username: String?) { 
    self.init(values: ["name": name, "uid": uid, "email": email, "username": username]) 
} 

これはあなたの他のものを無効にするべきではありません。

関連する問題