Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Return concrete object to generic method with generic Map parameter during override

Tags:

java

oop

generics

I have a generic method with generic Map parameter. I want to override it and use concrete subtype, but without cast I am not able to return my subtype

public interface GarrageSimple {
    <T extends Car> T getCar(Map<String, T> c);
}

Implementation is below which gives error as: Incompatible types. Required: T Found: Bmw

public class GarrageSimpleImpl implements GarrageSimple {

    @Override
    public <T extends Car> T getCar(Map<String, T> c) {
        return new Bmw();
    }
}

Actually, Bmw is a subclass of Car which means a type of T. When I cast it like * return (T)new Bmw();* it works with a warning that Unchecked cast Bmw to T

I know that it is because I take a risk to return concrete subclass while method signature is generic, but how I can change my method to make it concrete and not break override signature? If I can, in that case, it should work as expected.

PS: I don't want to make my class generic, I just need to change my method signature to make it concrete during implementation.

Thanks

like image 654
Vasif Avatar asked Nov 15 '25 10:11

Vasif


2 Answers

No, this is not valid. What would happen if someone with a GarrageSimpleImpl reference called it with a different class extending Car? Generics are all about compile time safety and that's why you get this error.

But you can do it like so,

public interface GarrageSimple<T extends Car> {
     T getCar(Map<String, T> c);
}


public class GarrageSimpleImpl implements GarrageSimple<Bmw> {
    @Override
    public Bmw getCar(Map<String, Bmw> c) {
        return new Bmw();
    }
}
like image 95
Ravindra Ranwala Avatar answered Nov 18 '25 00:11

Ravindra Ranwala


You can't. A generic method (a method which declares its own type parameters) means that your method must work no matter what the type parameters (here T) are. The method cannot choose what T to use. The caller can call your method with T being anything within the bounds of T, and your method must work correctly with whatever T is without choice.

A subclass overriding a method in a superclass means that the subclass method must be a valid substitute for the overridden method, which means that it must work in all situations that the overridden method can be called in. Since the overridden method is generic, and works for any T, your subclass method that overrides it must also work for any T. Your method does not work for any T -- it fails for any T that is not Bmw.

like image 31
newacct Avatar answered Nov 18 '25 00:11

newacct