我刚刚注意到 java.util.Observable 是一个具体的类。由于 Observable 的目的是扩展,这对我来说似乎很奇怪。以这种方式实施是否有原因?
我发现这篇文章说
observable 是一个具体的类,因此必须预先确定从它派生的类,因为 Java 只允许单继承。
但这并不能真正向我解释。事实上,如果 Observable 是抽象的,用户将被迫确定派生自它的类。
我刚刚注意到 java.util.Observable 是一个具体的类。由于 Observable 的目的是扩展,这对我来说似乎很奇怪。以这种方式实施是否有原因?
我发现这篇文章说
observable 是一个具体的类,因此必须预先确定从它派生的类,因为 Java 只允许单继承。
但这并不能真正向我解释。事实上,如果 Observable 是抽象的,用户将被迫确定派生自它的类。
很简单,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对象执行(类似地为>, <=, >=)作为第一种方法,人们可能会认为这样做是为了允许用户使用组合而不是继承,如果您的类已经从另一个类继承,并且您也不能从 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 类,我想说缺少“abstract”关键字只是一个“错误”。
我会说这门课完全是一团糟。