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

发布于 2024-12-02 15:25:54 字数 324 浏览 1 评论 0 原文

我刚刚注意到 java.util.Observable 是一个具体的类。由于 Observable 的目的是扩展,这对我来说似乎很奇怪。这样做有什么原因吗?

我发现这篇文章说的是

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

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

I just noticed that java.util.Observable is a concrete class. Since the purpose of Observable is to be extended, this seems rather odd to me. Is there a reason why it was implemented this way?

I found this article which says that

The observable is a concrete class, so the class deriving from it must be determined upfront, as Java allows only single inheritance.

But that doesn't really explain it to me. In fact, if Observable were abstract, the user would be forced to determine the class deriving from it.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

離人涙 2024-12-09 15:25:54

很简单,Observable 根本就是一个类,无论是抽象类还是其他类。

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

java 中有相当多的“错误”,包括:

%29" rel="noreferrer">Object.clone()soapbox,就语言本身而言,恕我直言:

  • == 应该执行 .equals() 方法(这会导致大量头疼)
  • 身份比较 == 应该是 === 像 javascript 或像 boolean isIdentical(Object o) 这样的专用方法,因为你很难永远需要它!
  • < 应该执行 compareTo(Object o) 0 对于 Comparable 对象(对于 ><=>= 也类似) )

Quite simply it's a mistake that Observable is a class at all, abstract or otherwise.

Observable should have been an interface and the JDK should have provided a convenient implementation (much like List is an interface and ArrayList is an implementation)

There are quite a few "mistakes" in java, including:

While on the soapbox, in terms of the language itself, IMHO:

  • == should execute the .equals() method (this causes loads of headaches)
  • identity comparison == should either be === like javascript or a dedicated method like boolean isIdentical(Object o), because you hardly ever need it!
  • < should execute compareTo(Object o) < 0 for Comparable objects (and similarly for >, <=, >=)
小帐篷 2024-12-09 15:25:54

作为第一种方法,人们可能会认为这样做是为了允许用户使用组合而不是继承,这非常方便如果您的类已经从另一个类继承,并且您不能从 Observable 类继承还。

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

private boolean changed = false;

,每次调用 notificationObservers 时都会检查该标志:

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”关键字只是一个“错误”。

我想说这堂课完全搞砸了。

As a first approach, one could think that this is done to allow the user to use composition instead of inheritance, which is very convenient if your class already inherits from another class, and you cannot inherit from Observable class also.

But if we look to the source code of Observable, we see that there is an internal flag

private boolean changed = false;

That is checked everytime the notifyObservers is invoked:

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);
    }

But from a class composed by this Observable, we cannot change this flag, since it is private, and the methods provided to change it are protected.

This means that the user is forced to subclass the Observable class, and I would say that the lack of the "abstract" keyword is just a "mistake".

I would say that this class is a complete screwup.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文