Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Call parent constructor when init a subclass in Swift

Tags:

swift

I've some classes which inherits from a base class. Usually with c++ classes I used to rewrite constructor in children and then call the parent one.

Is there a way in Swift to call parent constructor when init a subclass without rewriting it?

internal class A {
    init(aBool: Bool? = false) {
        ...
    }
}

class B: A {
    init(aString: String) {
        ...
    }
}

Having these two classes as example, I'd like to init B using the A constructor:

let obj = A(true)
like image 576
lucio Avatar asked Feb 16 '16 17:02

lucio


2 Answers

If you make B's init a convenience init it will not mask the original init and you will be able to do this...

class A {
    var b: Bool? = nil
    init(aBool: Bool? = false) {
        self.b = aBool
    }
}

class B: A {
    var s: String? = nil
    convenience init(aString: String) {
        self.init(aBool: false)
        self.s = aString
    }
}

let obj1 = A(aBool: true) // obj1 is now an A, obviously.
let obj2 = B(aBool: true) // obj2 is now a B

You'll have to be careful to default or otherwise set all properties, though...

Alternatively, you can override the original init in B, and simply call super.init.

like image 132
Grimxn Avatar answered Nov 11 '22 10:11

Grimxn


The rules from Apple state that:

[S]ubclasses do not inherit their superclass initializers by default. However, superclass initializers are automatically inherited if certain conditions are met. In practice, this means that you do not need to write initializer overrides in many common scenarios, and can inherit your superclass initializers with minimal effort whenever it is safe to do so.

Assuming that you provide default values for any new properties you introduce in a subclass, the following two rules apply:

Rule 1: If your subclass doesn’t define any designated initializers, it automatically inherits all of its superclass designated initializers.

Rule 2: If your subclass provides an implementation of all of its superclass designated initializers—either by inheriting them as per rule 1, or by providing a custom implementation as part of its definition—then it automatically inherits all of the superclass convenience initializers.

These rules apply even if your subclass adds further convenience initializers.

What does all that mean? If you make your subclass B's initializer a convenience initializer, then then B should inherit all of A's designated initializers.

class B: A {
    convenience init(aString: String) { ... }
}
like image 34
Aaron Rasmussen Avatar answered Nov 11 '22 09:11

Aaron Rasmussen