I used to believe I can always replace a protocol type with its conforming type, just like replacing a base class with a derived class.
However, I came across some weird behaviors when working with protocols.
Given:
protocol P { }
class C: P { }
In the case of conformance, the following code does not compile, the compiler says: " type 'Derived1' does not conform to protocol 'Base1"
protocol Base1 {
func foo() -> P
}
class Derived1: Base1 {
func foo() -> C { fatalError() }
}
In the case of inheritance, the following code does not compile neither, the compiler says: "method does not override any method from its superclass"
class Base2 {
func foo() -> P { fatalError() }
}
class Derived2: Base2 {
override func foo() -> C { fatalError() }
}
if I change P
to be a base class, in the latter case everything will fine, however the former case still fails.
What confuses me more is the face that it is actually covariant in theory. As the following valid line shows:
let foo: () -> P = { () -> C in
fatalError()
}
Can someone tell me, is my understanding about covariance corrent, or is it just an implementation limitation.