Reputation:
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
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
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
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