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

时间:2022-09-25 11:02:11

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?

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

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.

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

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.

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

2 个解决方案

#1


30  

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.

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

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

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

private boolean changed = false;

That is checked everytime the notifyObservers is invoked:

每次调用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);
    }

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.

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

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".

这意味着用户*继承Observable类,我会说缺少“abstract”关键字只是一个“错误”。

I would say that this class is a complete screwup.

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

#2


104  

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

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

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)

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

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

java中有很多“错误”,包括:

  • java.util.Stack is a class, not an interface (like Observable, bad choice)
  • java.util.Stack是一个类,而不是一个接口(比如Observable,糟糕的选择)
  • java.util.Properties extends java.util.Hashtable (rather than uses one)
  • java.util.Properties扩展java.util.Hashtable(而不是使用一个)
  • The java.util.Date class is a bit of a mess, and is not immutable!
  • java.util.Date类有点混乱,并不是一成不变的!
  • The java.util.Calendar class is a real mess
  • java.util.Calendar类是一个真正的混乱
  • No unsigned 'byte' type (this is a real pain and the source of many low-level bugs)
  • 没有无符号'字节'类型(这是一个真正的痛苦和许多低级错误的来源)
  • java.sql.SQLException is a checked exception
  • java.sql.SQLException是一个经过检查的异常
  • Arrays don't use Arrays.toString(array) as their default toString() (how many SO questions has this caused?)
  • 数组不使用Arrays.toString(array)作为默认的toString()(这导致了多少SO问题?)
  • Cloneable shouldn't be a marker interface; it should have the clone() method and Object.clone() should not exist
  • Cloneable不应该是标记接口;它应该有clone()方法,而Object.clone()不应该存在

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

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

  • == should execute the .equals() method (this causes loads of headaches)
  • ==应该执行.equals()方法(这会导致头痛)
  • identity comparison == should either be === like javascript or a dedicated method like boolean isIdentical(Object o), because you hardly ever need it!
  • 身份比较==应该是===像javascript或像boolean isIdentical(Object o)这样的专用方法,因为你几乎不需要它!
  • < should execute compareTo(Object o) < 0 for Comparable objects (and similarly for >, <=, >=)
  • <应该对comparable对象执行compareto(object o)<0(对于> ,<=,> =类似)

#1


30  

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.

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

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

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

private boolean changed = false;

That is checked everytime the notifyObservers is invoked:

每次调用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);
    }

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.

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

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".

这意味着用户*继承Observable类,我会说缺少“abstract”关键字只是一个“错误”。

I would say that this class is a complete screwup.

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

#2


104  

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

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

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)

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

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

java中有很多“错误”,包括:

  • java.util.Stack is a class, not an interface (like Observable, bad choice)
  • java.util.Stack是一个类,而不是一个接口(比如Observable,糟糕的选择)
  • java.util.Properties extends java.util.Hashtable (rather than uses one)
  • java.util.Properties扩展java.util.Hashtable(而不是使用一个)
  • The java.util.Date class is a bit of a mess, and is not immutable!
  • java.util.Date类有点混乱,并不是一成不变的!
  • The java.util.Calendar class is a real mess
  • java.util.Calendar类是一个真正的混乱
  • No unsigned 'byte' type (this is a real pain and the source of many low-level bugs)
  • 没有无符号'字节'类型(这是一个真正的痛苦和许多低级错误的来源)
  • java.sql.SQLException is a checked exception
  • java.sql.SQLException是一个经过检查的异常
  • Arrays don't use Arrays.toString(array) as their default toString() (how many SO questions has this caused?)
  • 数组不使用Arrays.toString(array)作为默认的toString()(这导致了多少SO问题?)
  • Cloneable shouldn't be a marker interface; it should have the clone() method and Object.clone() should not exist
  • Cloneable不应该是标记接口;它应该有clone()方法,而Object.clone()不应该存在

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

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

  • == should execute the .equals() method (this causes loads of headaches)
  • ==应该执行.equals()方法(这会导致头痛)
  • identity comparison == should either be === like javascript or a dedicated method like boolean isIdentical(Object o), because you hardly ever need it!
  • 身份比较==应该是===像javascript或像boolean isIdentical(Object o)这样的专用方法,因为你几乎不需要它!
  • < should execute compareTo(Object o) < 0 for Comparable objects (and similarly for >, <=, >=)
  • <应该对comparable对象执行compareto(object o)<0(对于> ,<=,> =类似)