Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java: generics inheritance confusion

Imagine we have following classes:

public interface MyInterface<T> {
    List<T> getList(T t);
}

abstract class BaseClass<T extends Number> implements MyInterface<T> {
    @Override
    public List<T> getList(Number t) {
        return null;
    }
}

class ChildClass extends BaseClass<Integer> {
    @Override
    public List<Integer> getList(Integer t) {
        return super.getList(t);  //this doesn't compile
    }
}

getList in ChildClass doesn't compile, the output is:

abstract method getList(T) in com.mypackage.MyInterface cannot be accessed directly

I can't get why BaseClass.getList method isn't overriden in ChildClass.

But what makes me completely confused is the fix that makes it compile:

class ChildClass extends BaseClass<Integer> {
    @Override
    public List<Integer> getList(Integer t) {
        return super.getList((Number) t);  //Now it compiles!
    }
}

So I cast Integer to Number, and is solves the problem.

Could anyone explain what's going on in this code?

like image 803
Denis Kniazhev Avatar asked May 24 '26 21:05

Denis Kniazhev


2 Answers

Your base class should look like:

abstract class BaseClass<T extends Number> implements MyInterface<T> {
    @Override
    public List<T> getList(T t) {
        return null;
    }
}

You weren't using T, but the Number class as a parameter.

like image 104
Marc Avatar answered May 26 '26 11:05

Marc


It doesn't override because the abstract method takes a Number as a parameter and the concrete method takes an Integer. They must be the same in order to override.

You should change your abstract class implementation to take type T as a parameter.

like image 36
Tyler Treat Avatar answered May 26 '26 11:05

Tyler Treat