编译时错误wrt java generic后面的解释?

时间:2014-09-21 08:12:51

标签: java generics

我正在研究设计问题,我必须设计一副牌。这是我的课程的样子

public interface ISuit {
    String getLogo();
    String getName();
}

public interface Icard<T extends ISuit> {
    T getSuit();
    String getNumber();
}

现在,我想为13张牌中的每张牌写一个类,这与本

的内容类似
public  class Queen<E extends ISuit> implements Icard<E> {
    @Override
    public String getNumber() {
        return "12";
    }

    @Override
    public E getSuit() {
        return new E;
    }

}

我打算像这样创造女王的对象 1:Queen<Hearts> queenOfhearts = new Queen<Hearts>();

但是,对于我的女王班,我有一个getSuit的编译时错误。我不知道 getSuit 的定义应该是什么。这个函数应该是抽象的吗?

3 个答案:

答案 0 :(得分:1)

在运行时,如果要实例化泛型类型T,则必须拥有Class<T>对象。

您可以将getSuit(..)方法的签名更改为:

public E getSuit(Class<E> clazz);

然后,实施将是:

public E getSuit(Class<E> clazz) {
    try {
        return clazz.newInstance();
    } catch (InstantiationException | IllegalAccessException e) {
    // TODO Auto-generated catch block
        e.printStackTrace();
    }
    return null;
}

更好的是,为了摆脱方法的Class<T>参数,您可以将其传递给类的构造函数并将其持久保存到私有成员。例如:

public  class Queen<E extends ISuit> implements Icard<E> {
    private Class<E> clazz;

    public Queen(Class<E> clazz) {
        this.clazz = clazz;
    }

    public String getNumber() {
        return "12";
    }

    public E getSuit() {
        try {
            return clazz.newInstance();
        } catch (InstantiationException | IllegalAccessException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return null;
    }
}

答案 1 :(得分:0)

使Queen成为实现getNumber()的抽象类。在getSuit()等派生类中实施QueenHearts

答案 2 :(得分:0)

首先,我认为从面向对象的方法来看,如何解决问题的想法是错误的。你想让Card成为一个有两个实例变量的类:number和suit。

然后,为了拥有13张牌中的每张牌,您可以创建13个对象并为其提供正确的卡号/套装。例如,

Suit hearts = new Suit("Hearts");
Card queenHearts = new Card(12,hearts);

关于编译时错误背后的实际原因,请查看Instantiating object of type parameter