web-dev-qa-db-ja.com

Java.util.Observableが抽象クラスではないのはなぜですか?

Java.util.Observableが具象クラスであることに気づきました。 Observableの目的は拡張されることなので、これは私にはかなり奇妙に思えます。このように実装された理由はありますか?

私は見つけました この記事 それはそれを言います

オブザーバブルは具象クラスであるため、Javaは単一の継承のみを許可するため、オブザーバブルから派生するクラスは事前に決定する必要があります。

しかし、それは私にはそれを本当に説明していません。実際、Observableが抽象的である場合、ユーザーはそれから派生するクラスを決定することを余儀なくされます。

最初のアプローチとして、これはユーザーが継承の代わりにコンポジションを使用できるようにするために行われると考えることができます。これは非常に便利ですクラスがすでに別のクラスから継承している場合そして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」キーワードの欠如は単なる「間違い」であると言えます。

このクラスは完全な失敗だと思います。

31
Mr.Eddart

非常に簡単に言えば、それは間違いということです Observable はクラスですまったく、抽象的またはその他。

Observableinterfaceである必要があり、JDKは便利な実装を提供する必要があります(Listがインターフェイスで、ArrayListが実装であるように)

Javaには、次のようなかなりの数の「間違い」があります。

  • Java.util.Stack はクラスであり、インターフェースではありません(Observableのように、悪い選択です)
  • Java.util.PropertiesextendsJava.util.Hashtableses oneではなく)
  • Java.util.Date クラスは少し混乱していて、notimmutable
  • Java.util.Calendar クラスはreal混乱です
  • 符号なしの「バイト」型はありません(これは本当に苦痛であり、多くの低レベルのバグの原因です)
  • Java.sql.SQLExceptionチェック済み 例外です
  • 配列はデフォルトArrays.toString(array)としてtoString()を使用しません(これが原因となったSO質問の数は?)
  • Cloneable マーカーインターフェイスであってはなりません。 clone()メソッドが必要であり、 Object.clone() が存在する必要がありますnot

soapbox にいる間、言語自体に関しては、私見:

  • _==_は.equals()メソッドを実行する必要があります(これにより多くの頭痛の種が発生します)
  • iDの比較_==_は、JavaScriptのような_===_か、boolean isIdentical(Object o)のような専用のメソッドである必要があります。これは、ほとんど必要ないためです。
  • _<_は、Comparableオブジェクトに対してcompareTo(Object o) < 0を実行する必要があります(同様に、_>_、_<=_、_>=_に対して)
109
Bohemian