¿Por qué java.util.Observable no es una clase abstracta?

Me di cuenta de que java.util.Observable es una clase concreta. Dado que el objective de Observable se extenderá, esto me parece bastante extraño. ¿Hay alguna razón por la cual se implementó de esta manera?

Encontré este artículo que dice que

Lo observable es una clase concreta, por lo que la clase que se deriva de ella debe determinarse por adelantado, ya que Java solo permite una herencia única.

Pero eso realmente no me lo explica. De hecho, si Observable fuera abstracto, el usuario se vería obligado a determinar la clase que se deriva de él.

Como primera aproximación, uno podría pensar que esto se hace para permitir al usuario usar composición en lugar de herencia, lo cual es muy conveniente si su clase ya hereda de otra clase , y tampoco puede heredar de la clase Observable.

Pero si miramos el código fuente de Observable, vemos que hay una bandera interna

 private boolean changed = false; 

Esto se verifica cada vez que se invoca 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); } 

Pero de una clase compuesta por este Observable, no podemos cambiar esta bandera , ya que es privada, y los métodos provistos para cambiarla están protegidos.

Esto significa que el usuario se ve obligado a subclasificar la clase Observable, y yo diría que la falta de la palabra clave “abstracta” es solo un “error”.

Yo diría que esta clase es una completa confusión.

Simplemente, es un error que Observable sea ​​una clase en absoluto , abstracta o no.

Observable debería haber sido una interfaz y el JDK debería haber proporcionado una implementación conveniente (al igual que List es una interfaz y ArrayList es una implementación)

Hay bastantes “errores” en Java, que incluyen:

  • java.util.Stack es una clase, no una interfaz (como Observable, mala elección)
  • java.util.Properties extiende java.util.Hashtable (en lugar de usar uno)
  • La clase java.util.Date es un poco desordenada, ¡y no es inmutable !
  • La clase java.util.Calendar es un verdadero desastre
  • Sin tipo ‘byte’ sin signo (esto es un verdadero dolor y la fuente de muchos errores de bajo nivel)
  • java.sql.SQLException es una excepción marcada
  • Las matrices no usan Arrays.toString(array) como su predeterminado toString() (¿cuántas preguntas SO ha causado esto?)
  • Cloneable no debería ser una interfaz de marcador; debería tener el método clone() y Object.clone() no debería existir

Mientras estoy en la tribuna , en términos del idioma en sí, en mi humilde opinión:

  • == debería ejecutar el método .equals() (esto causa un montón de dolores de cabeza)
  • la comparación de identidad == debería ser === como javascript o un método dedicado como boolean isIdentical(Object o) , ¡porque casi nunca lo necesitas!
  • < debería ejecutar compareTo(Object o) < 0 para objetos Comparable (y de manera similar para > , < = , >= )