Java Language Usando 'final' para restringir la herencia y anular


Ejemplo

Clases finales

Cuando se usa en una declaración de class , el modificador final evita que se declaren otras clases que extend la clase. Una clase final es una clase "hoja" en la jerarquía de clases de herencia.

// This declares a final class
final class MyFinalClass {
    /* some code */
}

// Compilation error: cannot inherit from final MyFinalClass
class MySubClass extends MyFinalClass {
    /* more code */
}

Casos de uso para las clases finales.

Las clases finales se pueden combinar con un constructor private para controlar o evitar la creación de instancias de una clase. Esto se puede usar para crear una llamada "clase de utilidad" que solo define miembros estáticos; Es decir, constantes y métodos estáticos.

public final class UtilityClass {

    // Private constructor to replace the default visible constructor
    private UtilityClass() {}

    // Static members can still be used as usual
    public static int doSomethingCool() {
        return 123;
    }

}

Las clases inmutables también deben ser declaradas como final . (Una clase inmutable es aquella cuyas instancias no se pueden cambiar después de haber sido creadas; consulte el tema Imutables de objetos ). Al hacer esto, hace imposible crear una subclase mutable de una clase inmutable. Eso violaría el principio de sustitución de Liskov, que exige que un subtipo obedezca el "contrato de comportamiento" de sus supertipos.

Desde una perspectiva práctica, declarar que una clase inmutable es final hace que sea más fácil razonar sobre el comportamiento del programa. También aborda los problemas de seguridad en el escenario donde el código no confiable se ejecuta en un entorno limitado de seguridad. (Por ejemplo, como String se declara como final , una clase confiable no tiene que preocuparse de que pueda ser engañada para que acepte una subclase mutable, que la persona que llama no de confianza podría cambiar de manera subrepticia).

Una desventaja de las clases final es que no funcionan con algunos marcos burlones como Mockito. Actualización: la versión 2 de Mockito ahora admite la burla de las clases finales.

Métodos finales

El modificador final también se puede aplicar a los métodos para evitar que se sobrescriban en las subclases:

public class MyClassWithFinalMethod {

    public final void someMethod() {
    }
}

public class MySubClass extends MyClassWithFinalMethod {

    @Override
    public void someMethod() { // Compiler error (overridden method is final)
    }
}

Los métodos finales se usan normalmente cuando se quiere restringir lo que una subclase puede cambiar en una clase sin prohibir por completo las subclases.


El modificador final también se puede aplicar a las variables, pero el significado de final para las variables no está relacionado con la herencia.