为什么java.util.Observable不是抽象类?

S.L*_*ica 49 java observable

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

我发现这篇文章说的是

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

但这并没有真正向我解释.实际上,如果Observable是抽象的,那么用户将被迫确定从中派生的类.

Boh*_*ian 109

很简单,Observable完全是一个类,抽象或其他方面都是错误的.

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

java中有很多"错误",包括:

肥皂盒上,就语言本身而言,恕我直言:

  • ==应该执行该.equals()方法(这会导致负担的头痛)
  • 身份比较==应该===像javascript或专用方法一样boolean isIdentical(Object o),因为你几乎不需要它!
  • <应该执行compareTo(Object o) < 0Comparable对象(并且类似地为>,<=,>=)

  • @ratchet_freak列表是一个接口,Map也是.你认为它们的实现要比Observable简单吗?不 - 他们不是.然而它们是接口.JDK应该提供一个Observable接口和一个实现,就像它提供Map接口和HashMap以及其他实现一样.我同意泛型部分. (7认同)
  • 看到这不是一个真正的答案(但是当人们同意这种流行的观点时收集了许多赞成票),它应该是社区维基. (5认同)
  • 它不能是一个接口,因为它有一个非常重要的实现.与addObserver/removeObserver的接口可能是不错的但老实说观察者应该是通用的(用E作为更新的参数) (3认同)
  • 我不能同意SQLException.它类似于IOException.除非你完全放弃了检查过的异常,这是另一个完整的主题,它肯定应该是其中之一. (3认同)

Mr.*_*art 31

作为第一种方法,人们可以认为这样做是为了允许用户使用组合而不是继承,如果你的类已经从另一个类继承,那么这是非常方便的,你也不能从Observable类继承.

但是如果我们查看Observable的源代码,我们会看到有一个内部标志

private boolean changed = false;
Run Code Online (Sandbox Code Playgroud)

每次调用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);
    }
Run Code Online (Sandbox Code Playgroud)

但是从这个Observable组成的类中,我们无法更改此标志,因为它是私有的,并且提供更改它的方法受到保护.

这意味着用户被迫继承Observable类,我会说缺少"abstract"关键字只是一个"错误".

我会说这个课程是完全搞砸了.