En primer lugar, recomiendo este artículo: Java: cuándo crear una clase final
Si lo hacen, ¿cuándo lo usan para que pueda entenderlo mejor y saber cuándo usarlo?
Una final
clase es simplemente una clase que no se puede extender .
(No significa que todas las referencias a objetos de la clase actuarían como si fueran declaradas como final
).
Cuando es útil declarar una clase como final está cubierto en las respuestas de esta pregunta:
Si Java está orientado a objetos y declaras una clase final
, ¿no detiene la idea de que la clase tenga las características de los objetos?
En cierto sentido si.
Al marcar una clase como final, deshabilita una característica potente y flexible del idioma para esa parte del código. Sin embargo, algunas clases no deberían (y en ciertos casos no pueden ) diseñarse para tener en cuenta las subclases de una buena manera. En estos casos, tiene sentido marcar la clase como final, a pesar de que limita la POO. (Recuerde, sin embargo, que una clase final todavía puede extender otra clase no final).
¡En Java, los elementos con el
final
modificador no se pueden cambiar!Esto incluye clases finales, variables finales y métodos finales:
fuente
final
modificador no se pueden cambiar!", Es demasiado categórica y, de hecho, no del todo correcta. Como dijo Grady Booch, "Un objeto tiene estado, comportamiento e identidad". Si bien no podemos cambiar la identidad de un objeto una vez que su referencia se ha marcado como final, sí tenemos la oportunidad de cambiar su estado mediante la asignación de nuevos valores a sus nofinal
campos (siempre que, por supuesto, los tenga). Cualquiera que sea planear obtener una Certificación Oracle Java (como 1Z0-808, etc.) debe tener esto en cuenta porque puede haber preguntas sobre este aspecto en el examen ...Un escenario donde final es importante, cuando desea evitar la herencia de una clase, por razones de seguridad. Esto le permite asegurarse de que alguien no pueda anular el código que está ejecutando .
Otro escenario es para la optimización: parece recordar que el compilador de Java incluye algunas llamadas de función de las clases finales. Entonces, si llama
a.x()
y se declara afinal
, sabemos en tiempo de compilación cuál será el código y podemos incorporarlo a la función de llamada. No tengo idea de si esto se hace realmente, pero con final es una posibilidad.fuente
El mejor ejemplo es
que es una clase inmutable y no se puede extender. Por supuesto, hay algo más que hacer que la clase final sea inmutable.
fuente
Lectura relevante: El principio abierto-cerrado de Bob Martin.
Cita clave:
La
final
palabra clave es el medio para aplicar esto en Java, ya sea que se use en métodos o en clases.fuente
final
la clase no se cierra por extensión en lugar de abrirse? ¿O lo estoy tomando demasiado literalmente?final
una declaración de clase / método no tendría sentido si desea que el código de implementación se cierre por modificación pero se abra por extensión por herencia.Si imagina la jerarquía de clases como un árbol (como lo es en Java), las clases abstractas solo pueden ser ramas y las clases finales son aquellas que solo pueden ser hojas. Las clases que caen en ninguna de esas categorías pueden ser tanto ramas como hojas.
Aquí no hay violación de los principios de OO, lo final es simplemente proporcionar una buena simetría.
En la práctica, desea usar final si desea que sus objetos sean inmutables o si está escribiendo una API, para indicar a los usuarios de la API que la clase simplemente no está destinada a la extensión.
fuente
La palabra clave en
final
sí misma significa que algo es definitivo y no se debe modificar de ninguna manera. Si una clase está marcada,final
entonces no se puede extender o subclasificar. Pero la pregunta es ¿por qué marcamos una clasefinal
? OMI hay varias razones:He oído que la clase de marcado
final
mejora la eficiencia, pero francamente no pude encontrar que este argumento tenga mucho peso.Quizás sí, pero a veces ese es el propósito previsto. A veces lo hacemos para lograr mayores beneficios de seguridad, etc. al sacrificar la capacidad de esta clase para extenderse. Pero una clase final aún puede extender una clase si es necesario.
En una nota al margen, deberíamos preferir la composición sobre la herencia y la
final
palabra clave realmente ayuda a hacer cumplir este principio.fuente
Tenga cuidado cuando haga una clase "final". Porque si desea escribir una prueba de unidad para una clase final, no puede subclasificar esta clase final para utilizar la técnica de ruptura de dependencia "Subclase y método de anulación" descrita en el libro de Michael C. Feathers "Trabajar eficazmente con código heredado" . En este libro, Feathers dijo: "En serio, es fácil creer que sellado y final es un error equivocado, que nunca deberían haberse agregado a los lenguajes de programación. Pero la verdadera falla recae en nosotros. Cuando dependemos directamente de bibliotecas que están fuera de nuestro control, solo estamos pidiendo problemas ".
fuente
final class
puede evitar romper la API pública cuando agrega nuevos métodosSupongamos que en la versión 1 de tu
Base
clase haces:y un cliente hace:
Entonces, si en la versión 2 desea agregar un
method
método paraBase
:rompería el código del cliente.
Si lo hubiéramos usado
final class Base
, el cliente no habría podido heredar, y la adición del método no rompería la API.fuente
Si la clase está marcada
final
, significa que la estructura de la clase no puede ser modificada por nada externo. Donde esto es más visible es cuando estás haciendo una herencia polimórfica tradicional, básicamenteclass B extends A
no funcionará. Básicamente es una forma de proteger algunas partes de su código (hasta cierto punto) .Para aclarar, la clase de marcado
final
no marca sus campos comofinal
y como tal no protege las propiedades del objeto, sino la estructura de clase real.fuente
PARA ABORDAR EL PROBLEMA DE CLASE FINAL:
Hay dos formas de hacer una clase final. El primero es usar la palabra clave final en la declaración de clase:
La segunda forma de hacer que una clase sea final es declarar a todos sus constructores como privados:
Marcarlo como final te ahorra el problema si descubres que es una final real, para demostrar que miras esta clase de Prueba. parece público a primera vista.
Desafortunadamente, dado que el único constructor de la clase es privado, es imposible extender esta clase. En el caso de la clase Test, no hay razón para que la clase sea final. La clase Test es un buen ejemplo de cómo las clases finales implícitas pueden causar problemas.
Por lo tanto, debe marcarlo como final cuando implícitamente realice una clase final haciendo que su constructor sea privado.
fuente
Una clase final es una clase que no se puede extender. Además, los métodos podrían declararse como finales para indicar que las subclases no pueden anularlos.
Evitar que la clase se subclasifique podría ser particularmente útil si escribe API o bibliotecas y desea evitar que se extienda para alterar el comportamiento base.
fuente
Una ventaja de mantener una clase como final:
La clase de cadena se mantiene final para que nadie pueda anular sus métodos y cambiar la funcionalidad. por ejemplo, nadie puede cambiar la funcionalidad del método length (). Siempre devolverá la longitud de una cadena.
El desarrollador de esta clase no quería que nadie cambiara la funcionalidad de esta clase, por lo que la mantuvo como final.
fuente
Sí, a veces es posible que desee esto, ya sea por razones de seguridad o velocidad. También se hace en C ++. Puede no ser tan aplicable para los programas, pero más aún para los marcos. http://www.glenmccl.com/perfj_025.htm
fuente
En java, la palabra clave final se usa para las siguientes ocasiones
fuente
Las clases finales no se pueden extender. Entonces, si desea que una clase se comporte de cierta manera y no alguien que anule los métodos (con un código posiblemente menos eficiente y más malicioso), puede declarar a toda la clase como métodos finales o específicos que no desea ser cambiado
Dado que declarar una clase no impide que se instancia una clase, no significa que evitará que la clase tenga las características de un objeto. Es solo que tendrá que atenerse a los métodos tal como se declaran en la clase.
fuente
Piense en FINAL como el "Fin de la línea": ese tipo ya no puede producir descendencia. Entonces, cuando lo ve de esta manera, hay un montón de escenarios del mundo real que encontrará que requieren que marque un marcador de 'fin de línea' a la clase. Es un diseño impulsado por dominio: si su dominio exige que una ENTIDAD (clase) determinada no pueda crear subclases, márquela como FINAL.
Debo señalar que no hay nada que le impida heredar una clase "debe etiquetarse como final". Pero eso generalmente se clasifica como "abuso de herencia", y se hace porque la mayoría de las veces le gustaría heredar alguna función de la clase base de su clase.
El mejor enfoque es mirar el dominio y dejar que dicte sus decisiones de diseño.
fuente
Como se dijo anteriormente, si desea que nadie pueda cambiar la funcionalidad del método, puede declararlo como final.
Ejemplo: ruta del archivo del servidor de aplicaciones para descarga / carga, división de cadena en función del desplazamiento, tales métodos puede declararlo Final para que estas funciones de método no se alteren. Y si desea tales métodos finales en una clase separada, defina esa clase como clase Final. Por lo tanto, la clase Final tendrá todos los métodos finales, donde el método Final se puede declarar y definir en una clase no final.
fuente
La clase Android Looper es un buen ejemplo práctico de esto. http://developer.android.com/reference/android/os/Looper.html
La clase Looper proporciona cierta funcionalidad que NO debe ser anulada por ninguna otra clase. Por lo tanto, no hay subclase aquí.
fuente
Digamos que tienes una
Employee
clase que tiene un métodogreet
. Cuandogreet
se llama al método, simplemente se imprimeHello everyone!
. Ese es el comportamiento esperado delgreet
métodoAhora, deje que la
GrumpyEmployee
subclaseEmployee
y anule elgreet
método como se muestra abajo.Ahora, en el siguiente código, eche un vistazo al
sayHello
método. TomaEmployee
instancia como parámetro y llama al método greet esperando que digaHello everyone!
Pero lo que obtenemos esGet lost!
. Este cambio de comportamiento se debe aEmployee grumpyEmployee = new GrumpyEmployee();
Esta situación se puede evitar si
Employee
se hizo la clasefinal
. Imagínense la cantidad de caos que un programador descarado podría causar siString
Class no se declarara comofinal
.fuente
La clase final no se puede extender más. Si no necesitamos hacer que una clase sea heredable en Java, podemos usar este enfoque.
Si solo necesitamos crear métodos particulares en una clase para no ser anulados, simplemente podemos poner la palabra clave final delante de ellos. Allí la clase todavía es heredable.
fuente
La orientación a objetos no se trata de herencia, se trata de encapsulación. Y la herencia rompe la encapsulación.
Declarar una final de clase tiene mucho sentido en muchos casos. Cualquier objeto que represente un "valor" como un color o una cantidad de dinero podría ser definitivo. Se paran solos.
Si está escribiendo bibliotecas, haga que sus clases sean finales a menos que explícitamente las sangría para que se deriven. De lo contrario, las personas pueden derivar sus clases y anular métodos, rompiendo sus suposiciones / invariantes. Esto también puede tener implicaciones de seguridad.
Joshua Bloch en "Java efectivo" recomienda diseñar explícitamente para la herencia o prohibirlo y señala que diseñar para la herencia no es tan fácil.
fuente