我刚才注意到java.util.Observable是一个具体的类。由于Observable的目的是扩展,这对我来说似乎很奇怪。有没有理由以这种方式实施?
我发现this article表示
observable是一个具体的类,因此必须事先确定从中派生的类,因为Java只允许单继承。
但这并没有真正向我解释。实际上,如果Observable是抽象的,那么用户将被迫确定从中派生的类。
答案 0 :(得分:107)
很简单,错误 Observable是一个类,抽象或其他类。
Observable
应该是接口,JDK应该提供了一个方便的实现(很像List
是一个接口而ArrayList
是一个实现)
java中有很多“错误”,包括:
Arrays.toString(array)
作为默认toString()
(这导致了多少SO问题?)Cloneable
不应该是标记界面;它应该有clone()
方法,Object.clone()
应该不 在soapbox上,就语言本身而言,恕我直言:
==
应执行.equals()
方法(这会导致令人头疼的问题)==
应该是===
,例如javascript或像boolean isIdentical(Object o)
这样的专用方法,因为你几乎不需要它!<
应为compareTo(Object o) < 0
个对象执行Comparable
(对于>
,<=
,>=
,答案 1 :(得分:30)
作为第一种方法,人们可以认为这样做是为了允许用户使用合成而不是继承,这非常方便如果你的类已经继承自另一个类,并且你不能继承来自Observable类也。
但是如果我们查看Observable的源代码,我们会看到有一个内部标志
private boolean changed = false;
每次调用notifyObservers时都会检查它:
public void notifyObservers(Object arg) {
Object[] arrLocal;
synchronized (this) {
if (!changed) return;
arrLocal = obs.toArray();
clearChanged();
}
for (int i = arrLocal.length-1; i>=0; i--)
((Observer)arrLocal[i]).update(this, arg);
}
但是来自这个Observable组成的类的,我们无法更改此标志,因为它是私有的,并且提供更改它的方法受到保护。
这意味着用户被迫继承Observable类,我会说缺少&#34; abstract&#34;关键字只是一个&#34;错误&#34;。
我会说这个课程是一个完整的搞砸。