【发布时间】:2015-02-22 01:37:01
【问题描述】:
要求
我正在尝试编写 Observer / Observable 一对类。我想对Observer 进行参数化,以便可以进行类型安全的更新调用。想象一下这个版本:
class View implements Observer<Model> {
@Override
public void update(Model model) { render(model); } // no casting:)
}
而不是需要转换的这个版本:
class View implements Observer {
@Override
public void update(Object model) { render((Model) model); } // casting:(
}
尝试
这是我目前所拥有的。我的Observer界面:
public interface Observer<T extends Observable> {
public void update(T observable);
}
还有我的Observable抽象类:
import java.util.List;
public abstract class Observable {
private List<Observer<? extends Observable>> observers;
public Observable() {
System.out.println(this.getClass());
}
public void addObserver(Observer<? extends Observable> obs) {
observers.add(obs);
}
public void removeObserver(Observer<? extends Observable> obs) {
observers.remove(obs);
}
protected <E extends Observable> void updateObservers(E self) {
for (Observer<? extends Observable> obs : observers) {
obs.update(self); // <-------------------- COMPILER ERROR!!!
}
}
}
问题
标有“编译器错误”的行与.update() 有问题:
Observer 类型中的方法 update(capture#4-of ? extends Observable) 不适用于参数 (E)
因此,即使传递给update() 的self 参数的类型是E extends Observable,它也不满足接口方法签名update(T observable); 其中T extends Observable。这是为什么?我真的希望它们能够兼容。
我可以解决这个问题以满足我的要求吗?
谢谢。
【问题讨论】:
-
仅仅因为
E扩展Observable并不意味着它会扩展任何扩展 Observable 的类(如通配符<? extends Observable>。 -
@hexafraction,看来编译器同意你的看法!你一定是对的,但我无法想象。你能举个例子吗?
E extends Observable为真,但它没有“扩展任何扩展 Observable 的类”的情况? -
这是一个反例:
class A extends Observable、class B extends Observable、class A1 extends A。obs的通配符将允许将Observer<B>分配给obs,在这种情况下,使用 A1 实例调用obs.update()将是无效的。我第一次的措辞有点不对。 -
@hexafraction,很有趣。谢谢你。也许我可以找到一种方法来收紧 obs (列表内容)的类型界限。显然通配符
? extends Observable太松了。也许如果我通过自身的子类参数化 Observable 类...... -
@hexafraction,成功了!!非常感谢你的帮助。我将在下面自行回答并参考您的评论。
标签: java generics design-patterns observer-pattern type-safety