Swift:在 Class 中实现协议初始化器

Swift: Implementing Protocol Initializer in a Class

我试图理解为什么 Swift 强制执行一个 class ,它符合一个带有初始化程序的协议,被标记为需要。这实质上强制任何子 classes 也实现该初始化器。指定的 superclass 初始化器肯定会被继承吗?

以下引述摘自 Swift 语言指南: https://developer.apple.com/library/prerelease/content/documentation/Swift/Conceptual/Swift_Programming_Language/Protocols.html#//apple_ref/doc/uid/TP40014097-CH25-ID272

You can implement a protocol initializer requirement on a conforming class as either a designated initializer or a convenience initializer. In both cases, you must mark the initializer implementation with the required modifier:

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
    }
}

The use of the required modifier ensures that you provide an explicit or inherited implementation of the initializer requirement on all subclasses of the conforming class, such that they also conform to the protocol.

编辑: 我最初没有提到我目前仅限于 Swift 2.1。它似乎是此版本中的编译器问题,在以后的版本中不会出现。

您不必强制在子类中实现初始化程序。考虑这个例子,它编译得很好:

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)

Surely the designated superclass initializer would be inherited?

不,不总是。如果子类定义了自己的指定初始化器,那么它不会自动继承超类的指定初始化器。考虑以下示例:

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:)指定初始化器,它不会自动继承Foo的指定初始化器init()。这可以防止在子类声明自己的存储属性的情况下进行不安全的初始化。

init() 标记为 required 强制执行 Bar 有一个 init(),通过提供自己的实现:

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没有定义它自己的指定初始化器时):

class Foo {
    required init() {}
}

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

let b = Bar() // legal