With your code, an instance of D
is an instance of C
, and consequently must accept any subclass of A as an argument to its abc()
method. What you want is an instance which only accepts a specific subclass. You need to generify C
(rather than just C#abc()
). Then you can make D
extend C<B>
, like so:
interface A {
}
interface B extends A {
}
abstract class C<T extends A> {
protected abstract void abc(T xyz);
}
class D extends C<B> {
@Override
protected void abc(B xyz) {
// Compiles
}
}
A proof that you can't generify the method only:
interface A {
}
interface B extends A {
public void def();
}
abstract class C {
protected abstract <T extends A> void abc(T xyz);
}
class D extends C {
@Override
protected void abc(B xyz) {
xyz.def();
}
public static void main(String[] args) {
D d = new D();
d.abc(new B(){}); // Invokes def() on a B, OK
C c = (C) d; // Cast to a C, OK
c.abc(new A(){}); // C#abc() applies to an A, but tries to invoke
// a's def(), which it lacks
}
}