0

I created a java project to apply my GraphTheory course and enhance my java skills.

In this project :

I created a class Sommet<S>(Vertex in English) with an attribute Id with a generic type called <S>.

I created a class Arc<S>(Edge in English) with two attributes Sommet(Vertex).

I created a class EnsembleArc which is an HashSet of Arc

I also created a class ArcValue which inherit from Arc and have an int attribute Valeur(Value in English)

Here everything is fine and I dont have any problem.

But then I created a class EnsembleArcValue which inherit from EnsembleArc because every method from EnsembleArc will be useful to EnsembleArcValue.

But I also want EnsembleArcValue to be an HashSet of ArcValue (and I dont want an Arc which is not an ArcValue). And with the inheritance EnsembleArcValue is able to have an "simple" Arc in his Set.

So my question after all this explanation is : Is there a way for EnsembleArcValue to inherit from EnsembleArc but will only accept an ArcValue in his Set.

Here is an image of The UML Project I hope it will help to understand my problem (dont look at the bottom).

Here is the code :

public class Sommet<S>
{
    //attributes
    private S id;

    public Sommet(S s)
    {
        setId(s);
    }

    public S getId() 
    {
        return id;
    }

    public void setId(S s) 
    {
        assert s!= null: "Objet null passé en paramètre";
        id = s;
    }

    @SuppressWarnings("unchecked")
    @Override
    public boolean equals(Object obj)
    {
        boolean callback;
        if(obj.getClass()!=getClass())
        {
            callback=false;
        }
        else
        {
            if(((Sommet<S>)obj).getId().equals(getId()))
            {
                callback=true;
            }
            else
            {
                callback=false;
            }
        }
        return callback;
    }

    @Override
    public int hashCode()
    {
        return getId().hashCode();
    }

    @Override
    public String toString()
    {
        return getId().toString();
    }
}

public class Arc<S>
{
    private Sommet<S> depart;
    private Sommet<S> arrivee;

    public Arc(Sommet<S> dep, Sommet<S> arr)
    {
        setDepart(dep);
        setArrivee(arr);
    }

    @Override
    public String toString()
    {
        String str="("+getDepart().getId()+","+getArrivee().getId()+")";
        return str;
    }


    public Sommet<S> getDepart() 
    {
        return depart;
    }
    public Sommet<S> getArrivee() 
    {
        return arrivee;
    }
    public void setDepart(Sommet<S> depart) 
    {
        this.depart = depart;
    }
    public void setArrivee(Sommet<S> arrivee) 
    {
        this.arrivee = arrivee;
    }

    @SuppressWarnings("unchecked")
    @Override
    public boolean equals(Object obj)
    {
        boolean callback;
        if(obj.getClass()!=getClass())
        {
            callback=false;
        }
        else
        {
            if(((Arc<S>)obj).getDepart().equals(getDepart())&&((Arc<S>)obj).getArrivee().equals(getArrivee()))
            {
                callback=true;
            }
            else
            {
                callback=false;
            }
        }
        return callback;
    }

    @Override
    public int hashCode()
    {
        return getArrivee().hashCode()+getDepart().hashCode();
    }
}

public class ArcValue<S,V> extends Arc<S>
{
    private V valeur;

    public ArcValue (Sommet<S> depart, Sommet<S> arrivee, V valeur)
    {
        super(arrivee,depart);
        this.valeur=valeur;
    }

    public V getValeur()
    {
        return valeur;
    }
}

import java.util.HashSet;
public class Ensemble<E> extends HashSet<E> implements Cloneable
{
    private static final long serialVersionUID = -4354387895748449845L;

    public Ensemble ()
    {
        super();
    }
    public Ensemble (Ensemble<E> ensemble)
    {
        for (E e : ensemble)
        {
            add(e);
        }
    }

    public String toString()
    {
        StringBuffer str=new StringBuffer("{");
        for(E e: this)
        {
            str=str.append(e.toString()+",");
        }
        str.setCharAt(str.length()-1, '}');
        return str.toString();
    }

    @SuppressWarnings("unchecked")
    @Override
    public Ensemble<E> clone()
    {
        return (Ensemble<E>)super.clone();
    }
}

public class EnsembleArc<S> extends Ensemble<Arc<S>>
{
    public EnsembleArc(Ensemble<Arc<S>> ensemble)
    {
        super(ensemble);
    }
    public EnsembleArc()
    {
        super();
    }

    private static final long serialVersionUID = -4099925554493145279L;


    public EnsembleSommet<S> listSucc(Sommet<S> sommet)
    {
        EnsembleSommet<S> XSucc=new EnsembleSommet<S>();
        for (Arc<S> arc : this)
        {
            if (arc.getDepart()==sommet)
            {
                XSucc.add(arc.getArrivee());
            }
        }
        return XSucc;
    }

    public EnsembleSommet<S> listPred(Sommet<S> sommet)
    {
        EnsembleSommet<S> XPred=new EnsembleSommet<S>();
        for (Arc<S> arc : this)
        {
            if (arc.getArrivee()==sommet)
            {
                XPred.add(arc.getDepart());
            }
        }
        return XPred;
    }

    public void add(Sommet<S> depart,Sommet<S>arrivee)
    {
        add(new Arc<S>(depart,arrivee));
    }
    @Override
    public EnsembleArc<S> clone ()
    {
        return (EnsembleArc<S>)super.clone();
    }
}

//import java.util.Collection;
public class EnsembleArcValues<S,V> extends EnsembleArc<S> //implements Collection<ArcValue<S,V>> 
{
    //TODO faire en sorte que ensembleArcValués ne  contienne que des ArcsValue
    private static final long serialVersionUID = -7163498825360866323L;
}

And you'll need this one to :

public class EnsembleSommet<S> extends Ensemble<Sommet<S>>
{
    public EnsembleSommet()
    {
        super();
    }
    public EnsembleSommet(EnsembleSommet<S> ensemble)
    {
        super(ensemble);
    }

    private static final long serialVersionUID = 7278825382690341067L;

    @Override
    public EnsembleSommet<S> clone ()
    {
        return (EnsembleSommet<S>)super.clone();
    }

    public Sommet<S> firstSommet()
    {
        @SuppressWarnings("unchecked")
        Sommet<S>[] tab=new Sommet[size()]; 
        return toArray(tab)[0];
    }
}

1 Answers1

1

The only way you can achieve this is to make the type of Arc you want part of your generic deceleration. Rename your existing EnsembleArc to AbstractEnsembleArc and change it's generic decleration from < S > to < S, T extends Arc< S > > i.e.:

public abstract class AbstractEnsembleArc<S, T extends Arc<S>> extends Ensemble<T> {
    // PUT ALL YOUR LOGIC CURRENTLY IN EnsembleArc HERE
}

Now create a new Class Called EnsembleArc and extend the new abstract class you've added, this new class will work identically to your existing EnsembleArc and class decleration should now look like:

public class EnsembleArc<S> extends AbstractEnsembleArc<S, Arc<S>> {
}

Finally have EnsembleArcValues extend the Abstract class instead of EnsembleArc so that you can declare that it should only accepts ArcValue and not simple Arc, do that like this:

public class EnsembleArcValues<S, V> extends AbstractEnsembleArc<S, ArcValue<S, V>> {
}
John Stringer
  • 558
  • 2
  • 6