Why can't Swift initializers call convenience initializers on their superclass?

Robert picture Robert · Jun 9, 2014 · Viewed 22.7k times · Source

Consider the two classes:

class A {
    var x: Int

    init(x: Int) {
        self.x = x
    }

    convenience init() {
        self.init(x: 0)
    }
}

class B: A {
    init() {
        super.init() // Error: Must call a designated initializer of the superclass 'A'
    }
}

I don't see why this isn't allowed. Ultimately, each class's designated initializer is called with any values they need, so why do I need to repeat myself in B's init by specifying a default value for x again, when the convenience init in A will do just fine?

Answer

Craig Otis picture Craig Otis · Jun 9, 2014

This is Rule 1 of the "Initializer Chaining" rules as specified in the Swift Programming Guide, which reads:

Rule 1: Designated initializers must call a designated initializer from their immediate superclass.

https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/Initialization.html

Emphasis mine. Designated initializers cannot call convenience initializers.

There is a diagram that goes along with the rules to demonstrate what initializer "directions" are allowed:

Initializer Chaining