在抽象类定义中使用2级泛型

时间:2012-04-27 05:59:27

标签: java

我有这个通用界面:

public interface TjbListener<T> {
    public void hearChange(T t);
}

我使用的是这样的:

public interface ObjectOneListener extends TjbListener<ClassOne> {

}

我想编写一个抽象泛型类A,它将泛型类型U作为参数,并且有一个方法(1),它本身在U上调用方法(2)。以下是我应该扩展的尝试(或实现也许?)通用的TjbListener接口。

public abstract class ListenerInformer<U extends TjbListener<"what should I write here">> {
    List<U> mListeners = new ArrayList<U>();

    public void addListener(U u){
        mListeners.add(u);
    }

    public void informAll("what should I write here"){
        for(U u:mListeners){
            u.hearChange("what should I write here");
        }
    }
}

我在编写这个问题时想到的一个解决方案如下,但我不知道它是否真的是一个解决方案,或者它是否有一些我不理解的微妙问题:

public abstract class ListenerInformer<U extends TjbListener<T>,T> {
    List<U> mListeners = new ArrayList<U>();

    public void addListener(U u){
        mListeners.add(u);
    }

    public void informAll(T t){
        for(U u:mListeners){
            u.hearChange(t);
        }
    }
}

更新:请注意

我刚刚发现这种方法对于我的特定情况几乎没用,因为同一个类不能用不同的参数实现相同的接口。请参阅下面链接的问题。这意味着我不能使用my(或Johanna's)解决方案让一个类成为两种不同类型的监听器,而不使用像合成这样的不同策略。

How to make a Java class that implements one interface with two generic types?

1 个答案:

答案 0 :(得分:3)

你的第二个例子应该有效。但是如果它就这么简单,则不需要Generic U,因为TjbListener的子类的每个实例也是TjbListener的实例。

你可以做得更简单:

public abstract class ListenerInformer<T> {
    List<TjbListener<T>> mListeners = new ArrayList<TjbListener<T>>();

    public void addListener(TjbListener<T> u){
        mListeners.add(u);
    }

    public void informAll(T t){
        for(TjbListener<T> u:mListeners){
            u.hearChange(t);
        }
    }
}

这就像你的代码一样,并且更容易处理。

如果您需要TjbListener的子类的最终实现类型作为参数的返回值,则需要两个泛型类型,例如,如果您有

 public U informAll2(T t){
    for(U u:mListeners){
        u.hearChange(t);
        if (...)
            return u;
    }
}

在这种情况下,你的两个泛型类型的声明是正确的(只是我不确定是否可以在声明T之前声明通用U,它取决于T,如果你必须先声明T,比如public abstract class ListenerInformer<T, U extends TjbListener<T>>