Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

java

generics

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?

like image 781
Pavel_K Avatar asked Aug 29 '17 17:08

Pavel_K


2 Answers

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) {...}  
}
like image 114
davidxxx Avatar answered Oct 16 '22 05:10

davidxxx


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.

like image 42
Dawood ibn Kareem Avatar answered Oct 16 '22 06:10

Dawood ibn Kareem