user5182503
user5182503

Reputation:

Name clash - have the same erasure yet neither overrides the other in method parameter generic

I have read all questions and answers about Name clash - have the same erasure yet neither overrides the other but still can't understand how to solve the problem. So,

@Dependent
public class SimpleFoo {}

@Dependent
public class AdvancedFoo extends SimpleFoo {}

@Dependent
public class Parent {

    @Inject
    protected void setFooInstance(Instance<? extends SimpleFoo> instance) {}
}

@Dependent
public class Child extends Parent {

    @Override
    protected void setFooInstance(Instance<AdvancedFoo> instance) {} //Error here
}

How to fix it?

Upvotes: 7

Views: 13320

Answers (3)

davidxxx
davidxxx

Reputation: 131346

The problem is that the Child class declares overriding the following method :

@Override
protected void setFooInstance(Instance<AdvancedFoo> instance) {} //Error here

but the Parent class declares a setFooInstance method that has a distinct signature :

protected void setFooInstance(Instance<? extends SimpleFoo> instance) {}

1) Either override the Child class in this way :

public class Child extends Parent {

    @Override
    protected void setFooInstance(Instance<? extends SimpleFoo> instance){... }
}

or 2) other way : if you want force the overrided method in the subclass to declare a specific SimpleFoo, make the Parent class a generic class parameterized with a SimpleFoo or a subclass of it :

@Dependent
public class Parent <T extends SimpleFoo>{

    @Inject
    protected void setFooInstance(Instance<T> instance) {...}
}

Now the Child class can be declared :

@Dependent
public class Child extends Parent<AdvancedFoo> {

    @Override
    protected void setFooInstance(Instance<AdvancedFoo> instance) {...}  
}

Upvotes: 6

aschoerk
aschoerk

Reputation: 3593

You would want Parent.setFooInstance to be callable with all possible descendants of Instance< SimpleFoo>. that would not hold for Objects of type Child since you would only be allowed to have Instance<Advanced> as Parameter. therefore it is not overridable in this way. Otherwise code only knowing the Parent class calling setFooInstance would possibly call with the objects of the wrong type. Therefore you either restrict the parameter of the Parent method to AdvancedFoo or allow Child.setFooInstance to also handle descendants of SimpleFoo.

Upvotes: 0

Dawood ibn Kareem
Dawood ibn Kareem

Reputation: 79838

You can do what you want if you make Child into a generic class. Then make Parent extend a particular type of Child, as shown.

public class Child<T extends SimpleFoo> {
    protected void setFooInstance(Instance<T> instance) {}
}

public class Parent extends Child<AdvancedFoo> {
    @Override
    protected void setFooInstance(Instance<AdvancedFoo> instance) {}
}

Incidentally, your naming is a little confusing. Most people would expect Child to extend Parent - not the other way around.

Upvotes: 1

Related Questions