如何在java中使用泛型超类型

时间:2016-09-10 18:21:23

标签: java generics

假设我有这些课程:

public interface Ordinal{}

public class One implements Ordinal {
    public static final One FIRST = new One();
}

public class Two extends One {
    public static final Two SECOND = new Two();
}

public class Three extends Two {
    public static final Three THIRD  = new Three();
}

然后是一个接口,其接受任何子类型Ordinal接口的方法。

public interface UseOrdinal<T extends Ordinal> {
    void use(T ordinal);
}

然后是实现接口的客户端。

public class Client implements UseOrdinal<Three> {

    @Override
    public void use(Three ordinal) {};
}

问题是Client的{​​{1}}方法只能接受类use的实例。但我希望它也会接受它的超级类型,例如ThreeOne。我怎样才能做到这一点?

编辑(添加问题上下文):我的应用程序中有大量不同的集合,范围从1到12个元素。因此,为了使其更具可读性并减少异常处理,我希望封装对其元素的访问,以便代替Two我将T get(int index),其中T get(Ordinal o)将仅包含特定的允许索引集合。

2 个答案:

答案 0 :(得分:0)

您必须将Client类设为通用,并将通用参数传递给UseOrdinal

public class Client<T extends Ordinal> implements UseOrdinal<T> {

    @Override
    public void use(T ordinal) {};
}

或者简单地将Ordinal作为泛型参数传递,因为所有类都是从它派生的:

public class Client implements UseOrdinal<Ordinal> {

    @Override
    public void use(Ordinal ordinal) {};
}

稍后在use方法正文中,您可以使用instanceof关键字检查传递的类:

@Override
public void use(T ordinal) {
    if (ordinal instanceof One) {
        // handle object of class One
    }
    else if (ordinal instanceof Two) {
        // handle object of class Two
    }
    else if (ordinal instanceof Three) {
        // handle object of class Three
    }
};

虽然,在我看来,拥有三个Client类来处理三种不同的Ordinal类型会更好(更多OOP)。

答案 1 :(得分:0)

根据上下文,以下可能是更好的方法。我假设你想避免IndexOutOfBounds的运行时检查。

public interface OneElementCollection<T> {

    T getFirst();
}

public interface TwoElementCollection<T> extends OneElementCollection<T> {

    T getSecond();
}

// etc.

正如@Jezor所提到的那样,设计有点值得怀疑,除非你需要像元组数据结构这样的东西,并且大小始终在[1..12]之内。