【问题标题】:Restrain the type while inheriting继承时限制类型
【发布时间】:2018-12-19 17:03:37
【问题描述】:

我创建了一个 java 项目来应用我的 GraphTheory 课程并提高我的 java 技能。

在这个项目中:

我创建了一个类 Sommet<S>(英文为 Vertex),其属性 Id 具有一个名为 <S> 的泛型类型。

我创建了一个类Arc<S>(英文的Edge),它有两个属性Sommet(Vertex)。

我创建了一个类EnsembleArc,它是ArcHashSet

我还创建了一个类ArcValue,它继承自Arc,并有一个int属性Valeur(英文值)

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

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

但我也希望EnsembleArcValue 成为ArcValueHashSet(而且我不希望Arc 不是ArcValue)。并且通过继承EnsembleArcValue 能够在他的Set 中有一个“简单”的Arc

在所有这些解释之后,我的问题是: EnsembleArcValue 有没有办法从EnsembleArc 继承,但在他的Set 中只接受ArcValue

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

代码如下:

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

你需要这个来:

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];
    }
}

【问题讨论】:

  • 是的,对不起,我不习惯在论坛上发布我的问题,如果我的代码在其他地方有错误,请在添加后随时告诉我

标签: java generics hashset


【解决方案1】:

实现此目的的唯一方法是将所需的 Arc 类型作为通用减速的一部分。将现有的 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>> {
}

【讨论】:

  • 有时间我会试试,但我想这正是我想要的,谢谢。
  • 效果很好,看来我得提高我的泛型技能了。再次感谢。
猜你喜欢
  • 1970-01-01
  • 2011-06-26
  • 1970-01-01
  • 2017-08-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-01-27
  • 1970-01-01
相关资源
最近更新 更多