I defined a simple class:
class MyClass { var name:String? required init() { println("init") } }
I can add a new initializer in an extension like this:
extension MyClass { convenience init(name: String) { self.init() self.name = name } }
Everything works fine.
But as soon as I define the new initializer in a protocol:
protocol MyProtocol { init(name:String) }
And make my extension confirm to that protocol:
extension MyClass : MyProtocol { convenience init(name: String) { self.init() self.name = name } }
I get the following error:
Initializer requirement 'init(name:)' can only be satisfied by a
required
initializer in the definition of non-final class 'MyClass'
What is going on here?
(BTW: I can't make my class final
, because this is only the extract of a more complicated use case.)
A protocol defines a blueprint of methods, properties, and other requirements. The protocol can then be adopted by a class, structure, or enumeration to provide an actual implementation of those requirements. But there would be a time when you want to restrict protocols to be adopted by a specific class.
A convenience initializer is a secondary initializer that must call a designated initializer of the same class. It is useful when you want to provide default values or other custom setup. A class does not require convenience initializers.
An initializer is a special type of function that is used to create an object of a class or struct. In Swift, we use the init() method to create an initializer. For example, class Wall { ... // create an initializer init() { // perform initialization ... } }
The convenience initializer must call one of the two designated initializers, because it can only call another initializer from the same class. This satisfies rules 2 and 3 from above. Both designated initializers must call the single designated initializer from the superclass, to satisfy rule 1 from above.
Ok, my bad.
To guarantee that all subclasses conform to MyProtocol
new initializer has to be marked as required
as well.
Furthermore Swift requires to declare all required initializers directly within the class and does not allow to declare them in extensions.
extension MyClass : MyProtocol { required convenience init(name: String) { self.init() self.name = name } }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With