2012-07-30 13 views
10

¿Hay alguna guía general sobre cuándo hacer una clase final?¿Circunstancias para hacer una clase final?

Pensé que era si no querías que la gente ampliara tu clase, pero parece un poco ... ingenuo?

+1

Creo que hay una gran cantidad de este tipo de preguntas aquí: http://stackoverflow.com/questions/2169668/why-would-you-make-a-whole-class-sealed-final por ejemplo –

+1

en cuenta la clase String, es final.Se requería que se mantuviera final y no se permitiera la extensión porque JVM mantiene grupos de cadenas, son inmutables. Si alguien lo reemplaza, eso crearía problemas para la JVM, es posible que no pueda mantener ninguna agrupación de cadenas porque la JVM no sabe cómo la clase extendida puede haber implementado algunos de sus métodos y puede crear problemas más grandes imposibles de rastrear. Entonces, TODO DEPENDE y requeriría una gran decisión de diseño ya sea para proporcionar una clase como FINAL o no. Definitivamente no utilizamos FINAL para las clases en el día a día. – devang

+0

¿Qué * otro criterio podría haber? – EJP

Respuesta

10

Al hacer que una clase final solo evite que se extienda a medida que observa. ¿Por qué querrías hacer eso?

  • Un caso de uso típico es para garantizar la inmutabilidad. Si diseñas una clase inmutable pero no la conviertes en definitiva, se puede ampliar de forma variable. Esto a su vez puede llevar a una subclase corrompiendo un invariante de clase o creando problemas de concurrencia.

  • También podría simplemente marcar una clase como final para documentar el hecho de que no está diseñada para ser extendida. Ver por ejemplo Effective Java # 17: "Diseñar y documentar para herencia o prohibirlo".

+0

Si los campos son finales, esto (en teoría) no es un problema. Aunque la reflexión rompe todas las reglas ... – user949300

+0

@ user949300 De acuerdo, pero un buen contraejemplo es BigDecimal, que es inmutable pero no definitivo, y tiene algunos campos que no son finales. Debería haber sido final en primer lugar. – assylias

+1

@assylias, aunque te marqué, no me gusta ver clases finales en bibliotecas mal mantenidas. Esto se debe a que restringe a los usuarios en sentido ascendente (¡yo!) De la implementación de soluciones extendiendo la clase y el código ofensivo '@ Override'ing. Si la biblioteca se mantiene activamente, entonces Bloch tiene toda la razón. – fommil

4

Está bien establecido que la herencia rompe la encapsulación. Allan Snyder en su artículo Encapsulation and inheritance in object-oriented programming languages demuestra la atención que debe ejercer con la herencia.

Josua Bloch en su libro Effective Java le recomienda diseñar y documentar sus clases para que sean heredadas o, de lo contrario, prohibirlas, refiriéndose precisamente a los problemas ya conocidos por Snyder.

Si en algún momento no está seguro de cómo se pueden ampliar sus clases en el futuro o si no tiene ninguna intención de que se extiendan, entonces probablemente sea mejor que sean definitivas. Siempre puede abrirlos para la extensión más tarde, pero al contrario (sobre todo si está construyendo un sistema abierto) puede ser una verdadera causa de dolor, si no imposible, según las circunstancias.

Las investigaciones de Mikhajlov y Sekerinski en su artículo A Study of the Fragile Base Class demuestran la variedad de problemas que puede tener al usar incorrectamente la herencia, lo que puede darle una idea más amplia de por qué esto podría ser importante.

5

Lo ideal es que haya leído a Josh Bloch y haya diseñado su clase para que funcione perfectamente. Pero, en la práctica, mi respuesta (en mi humilde opinión) para hacer una clase final es

¿Confía (o quiere) que otros lo extiendan?

Si se trata de una clase súper crítica como String o alguna clase relacionada con la seguridad, sí, definitivamente, que sea definitiva.

Si está haciendo cosas realmente sofisticadas y la clase sería difícil de extender correctamente, considere por lo que es definitivo, dependiendo de las habilidades que espera que tengan los que usan la clase. También depende de si se trata de una biblioteca de propósito general o de algún código específico de empresa/proyecto, y si es para un sitio web con videos Squirrel o un marcapasos cardíaco, es decir, ¿qué tan gravemente romperá una subclase pobre?

Si no está haciendo algo tan elegante, no moleste a los usuarios haciéndolo definitivo. A menudo he maldecido a Java por hacer clases como Double final.

+0

+1 contraparte de la vida real de mi teoría-vivimos-en-un-mundo perfecto; ;) – assylias

+2

@ user949300 ¿Qué tan gravemente una mala subclase romperá las cosas? En un sistema cerrado, probablemente pueda parchar cualquier problema que encuentre en el código donde se usa la clase. En un sistema abierto esto podría hacer que la clase sea imposible de corregir de manera adecuada, los usuarios probablemente tengan que vivir con el problema para siempre, simplemente porque hay miles de otros usuarios que confían en el contrato de una API rota, los usuarios que tienen extendió la clase y propagó sus fallas a aún más API. –

+1

@EdwinDalorzo OTOH, si la clase es 'final' y no anticipa todo lo que los usuarios desearían hacer (que es 100% cierto), las soluciones (" tratamiento ") podrían ser peores que la enfermedad. Entonces "depende". – user949300

Cuestiones relacionadas