Reputation: 183
While constructing a random graph I am trying to support 2 different edge types
TimestampEdge
DiffusionEdge
Each of which extend the generic Edge class
public class TimeStampEdge extends Edge<DiffusionVertex,Integer> {
//timestamp edge specific methods
}
public class DiffusionEdge extends Edge<DiffusionVertex,Integer> {
public DiffusionEdge(String name, DiffusionVertex v, DiffusionVertex v1) {
super(name, v, v1);
}
}
V is a self referential variable so that a vertex can maintain a list of its neighbours, and K just some value for an edge to have
public class Edge<V extends Vertex<?,V>,K> implements Edges<V,K> {
//Generic edge methods and values
}
What I want to do is be able to create a graph of both edge types from the same graph model, here's an example for random K-Trees. Where E should be either TimeStampEdge
or a DiffusionEdge
, diffusion vertex is the vertices used for all graph models, and GraphClass
is the abstract class all graph models inherit from.
public class KTree<E extends Edge<DiffusionVertex, Integer>> extends GraphClass<DiffusionVertex,E>
//ktree methods
public boolean addEdge(DiffusionVertex v, DiffusionVertex v1){
if(this.findEdgeSet(v,v1).isEmpty()){
v.setDegree(v.getDegree()+1);
v1.setDegree(v1.getDegree()+1);
E edge = (E) new Edge(v.getLabel() +"-"+v1.getLabel() ,v,v1);
this.Edges.put(edge.getHashCode(), edge);
return true;
}else{
return false;
}
}
//more ktree methods
}
I keep running into the java.lang.ClassCastException
where class Edge cannot be cast to TimeStampEdge
or DiffusionEdge
, I believe the problem comes from my instantiation of edges in the shown addEdge
method always being of the Edge class. However I'm not sure how to make it where i create edges of type E. Any help on how to go about doing this would be much appreciated!
Upvotes: 1
Views: 171
Reputation: 280
calling new Edge(...)
will not create any subclass of Edge represented as E unless E really does represent Edge. Java does not change the actual type of an object when you cast it from one type to another, let alone when you cast it to a generic type. For a cast to a specific type to work, the object itself must already be that type.
if you want to create a new E, maybe you can pass it a Supplier<E>
or use a factory pattern to create a new E properly.
Upvotes: 3