Protocol Extension with convenience init

I'm trying to use an extension on a class to add conformance to a protocol defining an alternate init() method and am running into a chain of errors that makes me think I'm missing something. Consider the following:

class ClassA {
    let str: String

    init(str: String) {
        self.str = str
    }
}

Assume this class is defined somewhere out of my control. I'd like to do the following:

protocol ProtoA {
    init(number: Int)
}

extension ClassA : ProtoA {
    convenience init(number: Int) {
        self.init(str: String(number))
    }
}

With this I get the error Initializer requirement 'init(number:)' can only be satisfied by a 'required' initializer in the definition of non-final class 'ClassA'. Ok, so I add required. Then I get 'required' initializer must be declared directly in class 'ClassA' (not in an extension).

Of course I can work around this by adding a static function to perform the initialization, but I don't understand why adding another initializer via an extension would be a problem in the first place. Any wisdom would be much appreciated :smile:

The problem arises when subclasses are involved.

Hmm ok, so I declare the conformance in ClassA and implement the initializer as required, then Swift forces all subclasses to also implement the required init method. This makes sense of course, but reduces the utility of allowing init() in a protocol at least for my use case.

As far as I understand, however, in order to actually call init(), you must have a concrete type -- perhaps the compiler could check/enforce compliance of the concrete type to the protocol at this point? I don't see a way that you could trick the compiler in that case, since SomeType.init() would need to be well formed.

Thoughts?

A subclass inherits the protocol conformances of its superclass.

If someone makes a subclass of ClassA, then that subclass also conforms to ProtoA.

Therefore, the implementation of the protocol requirements must be inherited by subclasses of ClassA.

Try making the initializer requirement optional in the protocol's body