First of all, pretty new in java, sorry if it is a simple question.
I have implemented an abstract class, and two classes that extends it.
public abstract class Lado{
//body
}
and the two other classes with this form for example
public class Arista extends Lado
{ //body
}
so, no problem there, now i have an interface defined like this.
public interface Grafo
{ //body
public List<Lado> lados();
//more body
}
has you see the interface returns a List of class Lado, but in my implementation I need to return a List of class Arista or the second class (on another implementation of the interface)
in the codebase that I HAVE to use for the interface implementation have the implementation of lados() like this
public List<Lado> lados() {
return lados;
}
with lados defined in my code like
private List<Arista> lados;
and initialized
lados = new LinkedList<Arista>();
now of course the return gives an error
GrafoNoDirigido.java:141: error: incompatible types
return lados;
^
required: List<Lado>
found: List<Arista>
1 error
I cant seem to find how to fix this without modifying the base code that was given to me (and I repeat cant change it). I know I cant instantiate an abstract class object and the abstract class implementation has values and functions that the abstract class doesn't.
Also I cant use override for the same reason that i cant change my functions signatures in my implementations.
I'll appreciate your help, thanks.
If anything reads weird, please let me know.
-------------------- EDIT --------- Lado abstract class.
public abstract class Lado
{
private String id;
private double peso;
public Lado(String id, double peso) {
this.id = id;
this.peso = peso;
}
public String getId() {
return id;
}
public double getPeso() {
return peso;
}
public abstract String toString();
}
Arista subclass
public class Arista extends Lado
{
private Vertice u;
private Vertice v;
public Arista(String id, double peso, Vertice u, Vertice v){
super(id , peso);
this.u = u;
this.v = v;
}
public Vertice getExtremo1() {
return u;
}
public Vertice getExtremo2() {
return v;
}
public String toString() {
String s = "string";
return s;
}
}
Then if I return a List<Lado>
if y try to do getExtremo1()
it doenst find the symbol on compilation (no existant on the Lado class), tried to cast the output list like a List<Arista>
but it didnt worked correctly either.
The problem is that Java doesn't have good support for "variance" for Enumerations (and no, it's not a simple question). Look here, under "The Workaround" for a solution: https://schneide.wordpress.com/tag/upcast/
If you can't change either the method return type or the variable declaration, you can return a copy:
Or you can return a wrapper:
Try changing your interface to:
public List lados();-- OR --
You can go another route and have the list be of the parent type with child instances:
Hope that helps!
Since class Artista is also Lado class, your initialization should be
So these are your constraints:
List<Lado>
).List<Arista>
1. Copying the array
2. Wrapping it as unmodifiable list*
3. Type erasure, don't do it, this is unsafe
Erasing the generics of your field before returning it. Unsafe since if someone adds an object that extends
Lado
but it's notArista
to that list you will have HeapPolution.