52

我刚刚注意到 java.util.Observable 是一个具体的类。由于 Observable 的目的是扩展,这对我来说似乎很奇怪。以这种方式实施是否有原因?

我发现这篇文章

observable 是一个具体的类,因此必须预先确定从它派生的类,因为 Java 只允许单继承。

但这并不能真正向我解释。事实上,如果 Observable 是抽象的,用户将被迫确定派生自它的类。

4

2 回答 2

116

很简单,Observable是一个类无论是抽象的还是其他的,这是一个错误。

Observable应该是一个接口,JDK应该提供一个方便的实现(很像List一个接口和ArrayList一个实现)

java中有不少“错误”,包括:

soapbox上,就语言本身而言,恕我直言:

  • ==应该执行该.equals()方法(这会导致很多头痛)
  • 身份比较==应该===像 javascript 或类似的专用方法boolean isIdentical(Object o),因为您几乎不需要它!
  • <应该compareTo(Object o) < 0Comparable对象执行(类似地为>, <=, >=
于 2011-09-02T13:43:33.117 回答
31

作为第一种方法,人们可能会认为这样做是为了允许用户使用组合而不是继承,如果您的类已经从另一个类继承,并且您也不能从 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”关键字只是一个“错误”。

我会说这门课完全是一团糟。

于 2011-09-02T14:57:12.260 回答