I am trying to understand the use of the required
keyword in Swift classes.
class SomeClass { required init() { // initializer implementation goes here } }
required
doesn't force me to implement the method in my child-class. If I want to override the required
designated initializer of my parent class I need to write required
and not override
. I know how it works but can not understand why I should do this.
What is the benefit of required
? As far as I can tell, languages like C# don't have something like this and work just fine with override
.
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 ... } }
Swift init() Initialization is the process of preparing an instance of a class, structure, or enumeration for use. This process involves setting an initial value for each stored property on that instance and performing any other setup or initialization that is required before the new instance is ready for use.
The required keyword means that inheriting classes must provide an implementation of the method. However, the language makes an exception for required initializers: You do not have to provide an explicit implementation of a required initializer if you can satisfy the requirement with an inherited initializer.
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.
It's actually just a way of satisfying the compiler to assure it that if this class were to have any subclasses, they would inherit or implement this same initializer. There is doubt on this point, because of the rule that if a subclass has a designated initializer of its own, no initializers from the superclass are inherited. Thus it is possible for a superclass to have an initializer and the subclass not to have it. required
overcomes that possibility.
One situation where the compiler needs to be satisfied in this way involves protocols, and works like this:
protocol Flier { init() } class Bird: Flier { init() {} // compile error }
The problem is that if Bird had a subclass, that subclass would have to implement or inherit init
, and you have not guaranteed that. Marking Bird's init
as required
does guarantee it.
Alternatively, you could mark Bird as final
, thus guaranteeing the converse, namely that it will never have a subclass.
Another situation is where you have a factory method that can make a class or its subclass by calling the same initializer:
class Dog { var name: String init(name: String) { self.name = name } } class NoisyDog: Dog { } func dogMakerAndNamer(whattype: Dog.Type) -> Dog { let d = whattype.init(name: "Fido") // compile error return d }
dogMakerAndNamer
is calling the init(name:)
initializer on Dog or a Dog subclass. But how can the compiler be sure that a subclass will have an init(name:)
initializer? The required
designation calms the compiler's fears.
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