6

Actualmente estoy leyendo Java efectivo por Joshua Bloch y el elemento 17 es 'Diseñar y documentar para herencia o prohibirlo'. El autor sugiere prohibir la herencia por defecto.¿Puede eliminar la finalización de una definición de clase romper la compatibilidad con versiones anteriores?

¿Es seguro declarar las clases final por defecto y en una versión posterior eliminar la palabra clave final si es necesario ampliar la clase? ¿Romperá la compatibilidad hacia atrás con el código compilado con una versión anterior?

Si es así, parece que es una apuesta más segura hacer que todas las clases sean definitivas y solo eliminarlas en versiones futuras si existe una demanda bien respaldada.

+0

Depende en cierta medida de la cantidad de API viva y respirable que tenga. Si realiza cambios y lanzamientos todo el tiempo, no es tan malo esperar una semana para obtener la capacidad de heredar. Si, por otro lado, Java hiciera eso con sus clases básicas de JDK por defecto, los programadores no tardarían en tener que esperar 5 años para la "solución". –

+0

@Kirk Woll si se necesitan 5 años para pasar de final a no final, ¿cuánto tiempo se tarda en pasar de no final a final? – emory

Respuesta

10

No rompe ni la compatibilidad binaria ni la fuente. Esa es una de las razones por las que es una buena idea hacer que las clases sean definitivas; siempre está bien cambiar de opinión al respecto.

The Java Language Specification, §13.4.2, tiene que decir lo siguiente acerca de la compatibilidad binaria:

Cambio de una clase que fue declarado final a ser declarada ya no final no se rompe la compatibilidad con los binarios pre-existente.

supongo que todavía podría compensar un ejemplo INTERPRETARÁN en que incluso se podría romper un programa; como bytecode, que genera una clase que hereda de la supuesta clase final, y luego carga esa clase generada y confía en obtener un VerifyError.

2

Mis pensamientos sobre esto:

Extracción de la final en una clase no causarán problemas inmediatos. Pero considere esto:

Hubo una clase final llamada AdamsFactory que cambia a no final. Dentro de dos meses, un nuevo programador llamado Dilbert se unirá a su equipo.
Subclasifica la clase que se acaba de usar en ScottFactory, pero rompe el Principio de Sustituibilidad de Liskov.

Luego tiene su clase ComicStripPrinter use ScottFactory en lugar de AdamsFactory. Algo está destinado a romperse.

Lo que nos lleva de nuevo a lo que dice Joshua bloque:

Si tiene la intención de herencia: Diseño con deliberación, y documentarla. Si no tiene la intención de heredar, entonces evítelo.

Espero que lo que dije no sea una gran carga de mierda.


EDIT:

ir en la preface of Java Langauge Specification, y la búsqueda de Joshua Bloch :)

+1

La persona que diseñó AdamsFactory no sabía si convertirlo en final/no final, por lo que PHB ordenó que sea no final (de manera predeterminada). Más tarde, Dilbert presenta un caso convincente para que AdamsFactory sea definitivo, pero en este momento hay alrededor de un billón de clases que extienden AdamsFactory rompiendo el Principio de Liskov. Si Dilbert hace el cambio, todas esas clases están rotas. Everone odia a Dilbert. – emory

2

Si está diseñando algo así como API estándar de Java, que millones de programadores utilizarán durante muchos años, sí , piensa como Joshua Bloch. ADELANTE EVOLUCIÓN es crucial.

El 99% de los programas de Java no lo son. Están desarrollados para uso interno, el impacto del cambio de API es pequeño, por lo general, todos los códigos fuente están disponibles para la refactorización.La SIMPLICIDAD es clave para tales programas. Si tienes diseños complejos y elegantes, o pasas todo el tiempo pensando en la final o no, estás perdiendo el tiempo.

Culpo a Joshua por no establecer los descargos de responsabilidad apropiados para sus sugerencias.

+2

Bueno, YAGNI está bien y elegante, pero cambiar tu plantilla de clase IDE Java para declarar todas las clases como 'final' es algo único, y un diseño de clase sensato siempre facilita el mantenimiento a largo y mediano plazo (a menudo, pero no siempre) , ayuda incluso a corto plazo), y navegar a una declaración de clase y eliminar 'final' es algo muy fácil de hacer, si cree que debería necesitarlo. – gustafc

+0

mientras estás en ello, haz que todos los campos y métodos sean definitivos también. – irreputable

Cuestiones relacionadas