继承时限制类型

时间:2018-12-19 17:03:37

标签: java generics hashset

我创建了一个Java项目来应用我的GraphTheory课程并增强我的Java技能。

在此项目中:

我创建了一个类Sommet<S>(英语中的顶点),该类具有一个属性ID,其泛型类型为<S>

我创建了一个具有两个属性Arc<S>(顶点)的类Sommet(英语为Edge)。

我创建了一个类EnsembleArc,它是HashSet的{​​{1}}

我还创建了一个类Arc,该类继承自ArcValue并具有int属性Arc(英语值)

这里一切都很好,我没有任何问题。

但是后来我创建了一个类Valeur,它继承自EnsembleArc,因为EnsembleArcValue中的每个方法对EnsembleArc都是有用的。

但是我也希望EnsembleArcValueEnsembleArcValue的{​​{1}}(并且我不希望HashSet不是ArcValue)。通过继承Arc,他的ArcValue可以拥有一个“简单” EnsembleArcValue

因此,经过所有这些解释之后,我的问题是: Arc是否可以从Set继承而只能在其EnsembleArcValue中接受EnsembleArc

这是The UML Project的图片 我希望这将有助于理解我的问题(不要看底部)。

这是代码:

ArcValue

Set

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();
    }
}

1 个答案:

答案 0 :(得分:1)

唯一可以实现此目的的方法是使所需的圆弧类型成为常规减速的一部分。将您现有的EnsembleArc重命名为AbstractEnsembleArc并将其通用定义从更改为>,即:

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

现在创建一个名为EnsembleArc的新类,并扩展您添加的新抽象类,该新类将与您现有的EnsembleArc相同,并且类分离现在应如下所示:

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

最后让EnsembleArcValues扩展Abstract类而不是EnsembleArc,以便您可以声明它只接受ArcValue而不接受简单的Arc,如下所示:

public class EnsembleArcValues<S, V> extends AbstractEnsembleArc<S, ArcValue<S, V>> {
}