How to avoid generic in hierarchy of classes?

Иван Гладуш :

I have next hierarchy of classes

   class MyObject {

}

class FirstChild extends MyObject {

}

class SecondChild extends MyObject {

}

class Calculator<T extends MyObject> {
    public Integer calculateValue(T supperObject) {
        return 10;
    }
}

class IntegerCalculator extends Calculator<FirstChild> {
    @Override
    public Integer calculateValue(FirstChild supperObject) {
        return super.calculateValue(supperObject);
    }
}

class SecondChildCalculator extends Calculator<SecondChild> {
    @Override
    public Integer calculateValue(SecondChild supperObject) {
        return super.calculateValue(supperObject);
    }
}


class AbstractUsefulService {
    protected Calculator<? extends MyObject> calculator;

    public AbstractUsefulService(
        Calculator<? extends MyObject> calculator
    ) {
        this.calculator = calculator;
    }
}

class ImplementationOfAbstractUsefulService extends AbstractUsefulService{

    public ImplementationOfAbstractUsefulService(
        SecondChildCalculator calculator
    ) {
        super(calculator);
    }

    public void doJob(){
        calculator.calculateValue(new SecondChild());
    }
}

I have a big problem here calculator.calculateValue(new SecondChild()); - required ? extends MyObject but found SecondChild. I've read a lot of articles and found only one solution and a generic to AbstractUsefulService and use this generic in ConnectionService, but I don't want to do it. How can I resolve my problem without generic in AbstractUsefulService?

Andy Turner :

How can I resolve my problem without generic in AbstractUsefulService?

You can't, if you are going to pass the calculator to AbstractUsefulService.

You need to know what type of object the calculator.calculateValue will accept.

The only way to do it would be to keep a reference in the ImplementationOfAbstractUsefulService class:

class ImplementationOfAbstractUsefulService extends AbstractUsefulService{
    private final SecondChildCalculator secondChildCalculator;

    public ImplementationOfAbstractUsefulService(
        SecondChildCalculator calculator
    ) {
        super(calculator);
    }

    public void doJob(){
        secondChildCalculator.calculateValue(new SecondChild());
    }
}

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=420451&siteId=1