Почему java.util.Observable не является абстрактным классом? - PullRequest
48 голосов
/ 02 сентября 2011

Я только что заметил, что java.util.Observable - это конкретный класс. Поскольку цель Observable должна быть расширена, это кажется мне довольно странным. Есть ли причина, почему это было реализовано таким образом?

Я нашел эту статью , в которой говорится, что

Observable - это конкретный класс, поэтому производный от него класс должен быть определен заранее, поскольку Java допускает только одно наследование.

Но это на самом деле мне не объясняет. Фактически, если бы Observable были абстрактными, пользователь был бы вынужден определить класс, производный от него.

Ответы [ 2 ]

107 голосов
/ 02 сентября 2011

Проще говоря, это ошибка , что Наблюдаемый - это класс вообще , абстрактный или иной.

Observable должен был быть интерфейс и JDK должны были обеспечить удобную реализацию (очень похоже на List - это интерфейс, а ArrayList - это реализация)

В java довольно много "ошибок", в том числе:

В то время как на мыльной коробке , с точки зрениясам язык, ИМХО:

  • == должен выполнять метод .equals() (это вызывает множество головных болей)
  • сравнение идентификаторов == должно быть ===javascript или специальный метод, такой как boolean isIdentical(Object o), потому что он вам вряд ли когда-нибудь понадобится!
  • < должен выполнить compareTo(Object o) < 0 для Comparable объектов (и аналогично для >, <=, >=)
30 голосов
/ 02 сентября 2011

В качестве первого подхода можно подумать, что это сделано для того, чтобы позволить пользователю использовать композицию вместо наследования, что очень удобно , если ваш класс уже наследуется от другого класса , и вы не можете наследовать от Наблюдаемый класс тоже.

Но если мы посмотрим на исходный код 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" является просто "ошибкой".

Я бы сказал, что этот класс - полный провал.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...