2017-02-22 64 views
2

我想了解爲什麼Swift強制一個類符合協議,初始化符被標記爲需要。這基本上強制任何子類也實現該初始化器。當然,指定的超類初始化器會被繼承?Swift:在一個類中實現協議初始化器

的報價低於從斯威夫特語言指南採取: https://developer.apple.com/library/prerelease/content/documentation/Swift/Conceptual/Swift_Programming_Language/Protocols.html#//apple_ref/doc/uid/TP40014097-CH25-ID272

您可以實現對符合 類無論是作爲指定初始化或便民初始化協議初始化要求。 在這兩種情況下,你必須標記與所需 修改初始化執行:

class SomeClass: SomeProtocol { 
    required init(someParameter: Int) { 
     // initializer implementation goes here 
    } 
} 

class SomeSubclass: SomeClass { 
    required init(someParameter: Int) { // enforced to implement init again 
     // initializer implementation goes here 
    } 
} 

的使用需要修改的,確保您在所有提供一個明確的 或繼承的執行初始化要求 符合類的子類,因此它們也符合 協議。

編輯: 我還沒有開始提到的,我目前僅限於雨燕2.1。它似乎是此版本中的編譯器問題,並且在更高版本中不會發生。

回答

3

當然指定的父類的初始化會遺傳嗎?

不,並不總是如此。如果子類定義了自己指定的初始化器,那麼它將不會自動繼承超類的指定初始器。請看下面的例子:

class Foo { 
    init() {} 
} 

class Bar : Foo { 

    var str: String 

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

let b = Bar() // illegal – what value would the 'str' property have? 

由於Bar定義了自己的init(str:)指定的初始化器,它不會自動繼承指定初始化器init()Foo的。這可以防止在子類聲明自己的存儲屬性的情況下進行不安全的初始化。

標記init()required強制Barinit(),無論是通過提供自己的實現:

class Foo { 
    required init() {} 
} 

class Bar : Foo { 

    var str: String 

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

    // implement required init(), as Bar defines its own designated initialiser. 
    required init() { 
     self.str = "foo" // now str is correctly initialised when calling init() 
    } 
} 

let b = Bar() // now legal 

或者通過繼承Foo的實現(當Bar沒有定義自己的指定initialisers) :

class Foo { 
    required init() {} 
} 

class Bar : Foo { 
    // inherits init() from Foo, as Bar doesn't define its own designed initialisers. 
} 

let b = Bar() // legal 
+0

這對於將其標記爲必需的推理有很多意義。我猜是什麼讓我吃驚的是,在Swift 2.1中,即使子類沒有指定的初始化器,編譯器也會強制你實現超類初始化器。 –

+0

將此標記爲已接受,因爲它解釋了我的問題「當然,指定的超類初始化程序會被繼承嗎?」原來的問題是由於Swift 2.1的限制。 –

2

你不強制在子類中實現初始化器。考慮下面這個例子,它編譯就好:

protocol SomeProtocol { 
    init(someParameter: Int) 
} 


class SomeClass: SomeProtocol { 
    required init(someParameter: Int) { 
     // initializer implementation goes here 
     print(someParameter) 
    } 
} 


class SomeSubclass: SomeClass { 
    // Notice that no inits are implemented here 
} 

_ = SomeClass(someParameter: 123) 
_ = SomeSubclass(someParameter: 456) 
+0

我應該提到我目前僅限於Swift 2.1所以ld是該版本中的一個錯誤。你編譯了哪個版本? –

+0

Swift 3. Swift 2已棄用。 – Alexander

+0

感謝您驗證版本。我瞭解它已被棄用,但由於我無法控制的情況,目前我僅限於使用它。很高興知道它已在更高版本中解決。 –