kdb*_*man 6 java generics design-patterns type-safety observer-pattern
要求
我正在尝试写一对Observer/ Observable类.我想参数化,Observer以便可以进行类型安全更新调用.想象一下这个版本:
class View implements Observer<Model> {
@Override
public void update(Model model) { render(model); } // no casting:)
}
Run Code Online (Sandbox Code Playgroud)
而不是需要强制转换的版本:
class View implements Observer {
@Override
public void update(Object model) { render((Model) model); } // casting:(
}
Run Code Online (Sandbox Code Playgroud)
尝试
这是我到目前为止所拥有的.我的Observer界面:
public interface Observer<T extends Observable> {
public void update(T observable);
}
Run Code Online (Sandbox Code Playgroud)
和我的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!!!
}
}
}
Run Code Online (Sandbox Code Playgroud)
问题
标有"COMPILER ERROR"的行有一个问题.update():
Observer类型中的方法更新(捕获#4-of?extends Observable)不适用于参数(E)
因此,即使self传递给的参数update()是类型E extends Observable,它也不满足接口方法签名update(T observable);所在T extends Observable.这是为什么?我真的希望那些兼容.
我可以解决这个问题以满足我的要求吗?
谢谢.
这是为什么?我真的希望它们能够兼容。
因为函数具有与类public void update(T observable);相同的泛型参数,这意味着它的参数类型应该与将调用该函数的引用变量的类型相同。TObserver<T extends Observable>update()
然而,当您尝试使用通配符时?,变量的类型obs可以是与方法参数的类型Observer<? extends Observable>扩展的任何不同的类。ObservableE
我可以解决这个问题以满足我的要求吗?
是的,使用Self Bound / Recursive Generics,一个具体的例子是Class Enum<E extends Enum<E>>,要理解这个概念,您可以看看下面的另请参阅部分。
所以,你的Observable意愿是这样的:
import java.util.List;
public abstract class Observable<T extends Observable<T>> {
private List<Observer<T>> observers;
public Observable() {
System.out.println(this.getClass());
}
public void addObserver(Observer<T> obs) {
observers.add(obs);
}
public void removeObserver(Observer<T> obs) {
observers.remove(obs);
}
protected void updateObservers(T self) {
for (Observer<T> obs : observers) {
obs.update(self);
}
}
}
Run Code Online (Sandbox Code Playgroud)
界面Observer:
public interface Observer<T extends Observable<T>> {
public void update(T observable);
}
Run Code Online (Sandbox Code Playgroud)
班上View:
class View implements Observer<Model> {
@Override
public void update(Model model) { render(model); }
}
Run Code Online (Sandbox Code Playgroud)
假设你的Model类应该是这样的:
public class Model extends Observable<Model>{
}
Run Code Online (Sandbox Code Playgroud)
也可以看看:
| 归档时间: |
|
| 查看次数: |
3723 次 |
| 最近记录: |