views:

102

answers:

2

Hello Is it possible to override a generisized function as illustrated in the code snippet below?

interface A {
}

interface B extends A {
}


abstract class C {
    protected abstract <T extends A> void abc(T xyz);
}

class D extends C {
    @Override
protected void abc(B xyz) {
    // doesn't compile
    // The method abc(B) of type D must override or implement a supertype method
    }
}

Thanks

A: 

Your class D should extend C<B>.

ankon
That won't work, as it's the function abc that's generic not the class C.
leftbrainlogic
+6  A: 

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
    }
}
roryparle
+1... beat me to it
RMorrisey
OK, Thanks. But what if you really only wanted to to generify C#abc, rather than C?
leftbrainlogic
I've edited the original answer to add some code demonstrating why you can't generify the method.
roryparle