0

我有这个通用接口:

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

我这样使用:

public interface ObjectOneListener extends TjbListener<ClassOne> {

}

我想编写一个抽象泛型类 A,它以泛型类型 U 作为参数,并有一个方法 (1),它本身在 U 上调用方法 (2)。下面是我的尝试 U 应该扩展(或可能实现?)通用 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);
        }
    }
}

更新:当心

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

如何制作一个实现一个接口和两个泛型类型的 Java 类?

4

1 回答 1

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 之前声明依赖于 T 的泛型 U,或者是否必须先声明 T,例如public abstract class ListenerInformer<T, U extends TjbListener<T>>

于 2012-04-27T07:30:39.110 回答