Given the following classes:
class A { public A a() {return new A();}; };
class B extends A { public B b() {return new B();} };
class C extends B { public C c() {return new C();} };
class D extends C { public D d() {return new D();} };
I want to write some UnaryOperator
s that can accept instances of A, B and C, but not D.
So my choice for declaring the reference type is UnaryOperator<? super C>
. Since I'm using super
, it means it can also accept an instance of Object
.
UnaryOperator<? super C> op1 = arg -> arg.a(); // does not compile, arg could be Object
UnaryOperator<? super C> op2 = arg -> arg.b(); // does not compile, arg could be Object
UnaryOperator<? super C> op3 = arg -> arg.c(); // does compile
UnaryOperator<? super C> op4 = arg -> arg.d(); // this is not expected to compile
Why does op1
makes the code fail to compile with a message
Type mismatch: cannot convert from A to C
and op2
makes the code fail to compile with a message
Type mismatch: cannot convert from B to C
,
but op3
compiles fine, and let me call a method available only in C?