简体   繁体   中英

Java generics and inheritance

I have the following abstract classes:

public abstract class AbSuperClass1<K,S> {
    //class definition
}

and:

public abstract class AbSuperClass2<K,S> {
    public abstract <Q extends AbSuperClass1<K,S>> void method(Q arg);
    ...
}

I then have two concrete implementations

public class Concrete1 extends AbSuperClass<String, String>{
    //class definition
}

and:

public class Concrete2 extends AbSuperClass2<String, String>{
    public void method(Concrete1 arg){
        //method definition
    }
}

This will not, however, compile, as Concrete1 is not recognised as a valid type for the argument of method in Concrete2, but as far as I can see Concrete1 is of the correct type, since it extends AbSuperClass1.

Where am I going wrong?

Consider this program:

public class OtherConcrete extends AbSuperClass<String, String> {}

AbSuperClass2<String, String> x = new Concrete2();
x.method(new OtherConcrete());

What would you expect that to do? You've overridden method in terms of providing an implementation for one specific subtype of AbSuperClass<String, String> - but you haven't provided an implementation which can cope with any AbSuperClass<String, String> , which is what's required.

It's hard to suggest a particular course of action without knowing the details of the situation. Bozho's suggestion of adding another type parameter - allowing you to make the method declaration more specific - is a good one... but the whole thing is becoming very complicated. If you can work out any way to reduce the amount of generic funkiness going on, your code maintainers would probably thank you for it.

Eclipse suggested adding this method:

@Override
public <Q extends AbSuperClass1<String, String>> void method(Q arg) {
    // TODO Auto-generated method stub

}

Another thing you can do, is add this type parameter to the class:

abstract class AbSuperClass2<K,S, Q extends AbSuperClass1<K,S>> {
    public abstract void method(Q arg);
}

and

class Concrete2 extends AbSuperClass2<String, String, Concrete1> {
    public void method(Concrete1 arg) {
        //method definition
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM