Swift: Implementing Protocol Initializer in a Class

前端 未结 2 851
长发绾君心
长发绾君心 2021-01-22 03:34

I am trying to understand why Swift enforces a class that conforms to a protocol with an initializer to be marked as required. This essentially enforces any subclasses to also i

相关标签:
2条回答
  • 2021-01-22 03:54

    You're not force to implement the initializer in the subclass. Consider this example, which compiles just fine:

    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 讨论(0)
  • 2021-01-22 04:17

    Surely the designated superclass initializer would be inherited?

    No, not always. If the subclass defines its own designated initialisers, then it won't automatically inherit the superclass' designated initialisers. Consider the following example:

    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?
    

    As Bar defines its own init(str:) designated initialiser, it doesn't automatically inherit Foo's designated initialiser init(). This prevents unsafe initialisation in cases where the subclass declares its own stored properties.

    Marking init() as required enforces Bar has an init(), be it through providing its own implementation:

    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
    

    Or by inheriting Foo's implementation (when Bar doesn't define its own designated 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 讨论(0)
提交回复
热议问题