Reputation: 13043
I have this code:
public protocol MyProtocol {
init()
}
public extension MyProtocol {
public init() {
self.init()
}
}
public final class MyClass: MyProtocol {}
I got an error saying:
Initializer 'init()' must be declared public because it matches a requirement in public protocol 'MyProtocol'
If I remove the access control (public
) before final
, it works. But why? Is there any way I can let the protocol handle the init? I thought all members of protocols are implicitly public
by default.
More strange is that a different init
that can only be found in the extension
is public
by default:
public protocol MyProtocol {
init()
}
public extension MyProtocol {
public init() {
self.init()
}
public init(youDoNotHaveToImplementMe: Any) {
self.init()
}
}
public final class MyClass: MyProtocol {
public init() {}
}
As you can see, the new init is actually public
. I expected my normal init
should be public
as well. Why is this not the case?
Upvotes: 2
Views: 723
Reputation: 5348
MyClass
is supposed to conform to given protocol MyProtocol
, even if MyClass
is public. But how would MyClass
conform to MyProtocol
, if MyClass
were public but its init not visible from the other module? It would conform to MyProtocol
(signature says so) and at the same time not(no visible init).
Since your protocol can't be certain to cover all members of the class that uses it, any initializer you declare in your protocol will need to delegate initialization of the "unknown" members of the class to another initializer provided by the class itself.
Since MyClass
‘ default initializer is internal the protocol does not conform to the protocol if no public init is declared in-class while MyClass
is public.
Upvotes: 2