Mientras uno de De Java fortalezas es el concepto de herencia, en el que uno clase puede derivarse de otra, a veces es deseable evitar la herencia de otra clase. Para evitar la herencia, use la palabra clave "final" al crear la clase.
Por ejemplo, si es probable que otros programadores usen una clase, es posible que desee evitar la herencia si alguna de las subclases creadas puede causar problemas. Un ejemplo típico es el Clase de cadena. Si quisiéramos crear una subclase de String:
MyString de clase pública extiende String {
}
Nos enfrentaremos a este error:
no puede heredar de java.lang final. Cuerda
Los diseñadores de la clase String se dieron cuenta de que no era candidato a la herencia y evitaron que se extendiera.
¿Por qué prevenir la herencia?
La razón principal para prevenir herencia es asegurarse de que una subclase no corrompa el comportamiento de una clase.
Supongamos que tenemos una clase Cuenta y una subclase que la extiende, OverdraftAccount. Cuenta de clase tiene un método getBalance ():
public double getBalance ()
{
devuelve this.balance;
}
En este punto de nuestra discusión, la subclase OverdraftAccount no ha anulado este método.
(Nota: Para otra discusión usando esta clase de Cuenta y Cuenta de Sobregiro, vea cómo la subclase puede tratarse como una superclase).
Creemos una instancia de cada una de las clases Account y OverdraftAccount:
Cuenta bobsAccount = nueva cuenta (10);
bobsAccount.depositMoney (50);
OverdraftAccount jimsAccount = new OverdraftAccount (15.05,500,0.05);
jimsAccount.depositMoney (50);
// crea una matriz de objetos de Cuenta
// podemos incluir jimsAccount porque
// solo quiero tratarlo como un objeto de Cuenta
Cuenta [] cuentas = {bobsAccount, jimsAccount};
// para cada cuenta en la matriz, muestra el saldo
para (Cuenta a: cuentas)
{
System.out.printf ("El saldo es% .2f% n", a.getBalance ());
}
El resultado es:
El saldo es de 60.00.
El saldo es 65.05
Todo parece funcionar como se esperaba, aquí. Pero, ¿qué pasa si OverdraftAccount anula el método getBalance ()? No hay nada que evite que haga algo como esto:
OverdraftAccount de clase pública extiende la Cuenta {
sobregiro doble privado Límite;
sobregiro doble privado
// el resto de la definición de clase no está incluida
public double getBalance ()
{
devolver 25.00;
}
}
Si el código de ejemplo anterior se ejecuta nuevamente, el resultado será diferente porque el comportamiento getBalance () en la clase OverdraftAccount se llama para jimsAccount:
El resultado es:
El saldo es de 60.00.
El saldo es de 25.00.
Desafortunadamente, la subclase OverdraftAccount Nunca proporcionar el saldo correcto porque hemos corrompido el comportamiento de la clase Cuenta a través de la herencia
Si diseña una clase para ser utilizada por otros programadores, siempre considere las implicaciones de cualquier subclase potencial. Esta es la razón por la cual la clase String no se puede extender. Es extremadamente importante que los programadores sepan que cuando crean un objeto String, siempre se comportará como un String.
Cómo prevenir la herencia
Para evitar que una clase se extienda, la declaración de clase debe decir explícitamente que no se puede heredar. Esto se logra utilizando la palabra clave "final":
Cuenta de clase final pública {
}
Esto significa que la clase Account no puede ser una superclase, y la clase OverdraftAccount ya no puede ser su subclase.
A veces, es posible que desee limitar solo ciertos comportamientos de una superclase para evitar la corrupción de una subclase. Por ejemplo, OverdraftAccount aún podría ser una subclase de Account, pero se debe evitar que anule el método getBalance ().
En este caso, utilice la palabra clave "final" en la declaración del método:
Cuenta de clase pública {
doble saldo privado;
// el resto de la definición de clase no está incluida
public final double getBalance ()
{
devuelve this.balance;
}
}
Observe cómo la palabra clave final no se usa en la definición de clase. Se pueden crear subclases de cuenta, pero ya no pueden anular el método getBalance (). Cualquier código que llame a ese método puede estar seguro de que funcionará según lo previsto por el programador original.