Norbi
02/05/2023, 11:47 AMinterface C<B>
interface C1<B> : C<B>
interface C2<B, F : B> : C<B>
interface D<B, F : B, T : B> {
val f: (C<B>) -> T
}
interface D1<B, T : B> : D<B, Nothing, T> {
override val f: (C1<B>) -> T // Compile error: not a subtype type of overridden ...
}
interface D2<B, F : B, T : B> : D<B, F, T> {
override val f: (C2<B, F>) -> T // Compile error: not a subtype type of overridden ...
}
Roukanken
02/05/2023, 12:20 PMinterface SuperType
interface SubType1: SuperType
interface SubType2: SuperType
interface Contract {
val f: (SuperType) -> Unit
}
interface SubContract1 : Contract {
override val f: (SubType1) -> Unit // Compile error: not a subtype type of overridden ...
}
interface SubContract2 : Contract {
override val f: (SubType2) -> Unit // Compile error: not a subtype type of overridden ...
}
Why? It's because it's a function argument. Consider this: we wouldn't get an error here, and we would have succefully implemented SubContract1Impl
somehow.
Now this code:
// it's the implementation, so it's subtype of it
val subContract1: SubContract1 = SubContract1Impl()
// SubContract1 extends Contract
val contract: Contract = subContract1
// SubType2 is subtype of SuperType, so this passes
// but whoever implemented f, only expected SubType1...
contract.f(SubType2Impl())
(A1) -> B1
is subtype of (A2) -> B2
only when B1
is subtype of B2
, and A2
is subtype of A1
Notice the order.Norbi
02/05/2023, 12:40 PM