在抽象类定义

问题描述:

我有这样的通用接口,使用2级仿制药:在抽象类定义

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); 
     } 
    } 
} 

UPDATE:谨防

我刚刚发现,这种做法对我的具体情况几乎是无用的,因为同一类无法实现用不同的参数相同的接口。看到下面链接的问题。这意味着我不能用一个类作为我的(或约翰娜的)解决方案的两种不同类型的听众,而不使用不同的组合策略。

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

+0

我想知道,你尝试了什么问题解决?它看起来有点过度设计... – aviad 2012-04-27 06:03:00

+1

我认为你的解决方案是好的 – 2012-04-27 06:04:40

+0

我第二,你的解决方案很好,我不同意@aviad,它没有被过度强调。 – Snicolas 2012-04-27 06:05:37

你的第二个例子应该工作。但是,如果它如此简单,那么就不需要通用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>>

+0

,这对我来说确实起作用,因为我没有返回任何东西。谢谢您的深入解释 – tjb 2012-04-27 08:22:55

+0

oops,抱歉,您的解决方案存在另一个问题,我之前没有看到:输入到addListener的参数未经过类型检查。 T的值必须已经在TjbListener接口中指定为listenChange的输入参数,这是不正确的。 – tjb 2012-04-27 08:30:01

+0

是的,你说得对。我忘了参数化TjbListener。我添加了缺失的''。现在应该会更好。 – Johanna 2012-04-27 08:44:06