Почему java.util.Observable не абстрактный класс?
Я только заметил, что java.util.Observable - это конкретный класс. Поскольку цель Observable должна быть расширена, это кажется мне довольно странным. Есть ли причина, почему это было реализовано таким образом?
Я нашел эту статью, в которой говорится, что
Наблюдаемый - это конкретный класс, поэтому класс, вытекающий из него, должен быть определен заранее, поскольку Java допускает только одно наследование.
Но это на самом деле не объясняет это мне. Фактически, если Observable были абстрактными, пользователь был бы вынужден определить класс, вытекающий из него.
Ответы
Ответ 1
В качестве первого подхода можно подумать, что это делается для того, чтобы пользователь мог использовать композицию вместо наследования, что очень удобно , если ваш класс уже наследуется от другого класса, и вы не можете наследовать из класса 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, и я бы сказал, что отсутствие "абстрактного" ключевого слова - это просто "ошибка".
Я бы сказал, что этот класс является полным отвращением.
Ответ 2
Совсем просто ошибка, что Observable - это класс вообще, абстрактный или другой.
Observable
должен был быть интерфейсом, и JDK должен был обеспечить удобную реализацию (так же, как List
является интерфейсом, а ArrayList
является реализацией)
В java существует немало "ошибок", в том числе:
Пока на soapbox, с точки зрения самого языка, IMHO:
-
==
должен выполнить метод .equals()
(это вызывает множество головных болей)
- сравнение идентичности
==
должно быть либо ===
, как javascript, или выделенный метод, например boolean isIdentical(Object o)
, потому что вам он вряд ли когда-либо понадобится!
-
<
должен выполнить compareTo(Object o) < 0
для Comparable
объектов (и аналогично для >
, <=
, >=
)