我有这个通用界面:
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?
答案 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>>
)