Array

Cómo prevenir la herencia en Java usando la palabra clave final

Computer programmers working

Si bien una de las fortalezas de Java & amp; apos; es el concepto de herencia, en el que una clase puede derivarse de otra, a veces es deseable evitar la herencia de otra clase. Para evitar la herencia, use la palabra clave & amp; quot; final & amp; quot; al crear la clase.

Por ejemplo, si es probable que otros programadores utilicen una clase, es posible que desee evitar la herencia si alguna subclasificación creada podría causar problemas. Un ejemplo típico es la clase String. Si quisiéramos crear una subclase de cadena:

Video destacado
& lt; pre / & gt; & lt; pre & gt; clase pública MyString extiende String {& lt; br & gt ;
& amp; # xFEFF;} & lt; / br & gt; & lt; / pre & gt ;

Nos enfrentaríamos a este error:

& lt; pre / & gt; & lt; pre & gt; no puede heredar de java.lang.String & lt; / pre & gt ;

Los diseñadores de la clase String se dieron cuenta de que no era un candidato para la herencia y han impedido que se extienda.

¿Por qué prevenir la herencia??

La razón principal para evitar la herencia es asegurarse de que la forma en que se comporta una clase no esté corrompida por una subclase.

Supongamos que tenemos una cuenta de clase y una subclase que la extiende, OverdraftAccount. La cuenta de clase tiene un método getBalance ():

& lt; pre / & gt; & lt; pre & gt; público doble getBalance () & lt; / pre & gt ;
& lt; br & gt ;
& lt; pre & gt; {& lt; / pre & gt ;
& lt; br & gt ;
& lt; pre & gt; devolver este saldo; & lt; / pre & gt ;
& lt; br & gt ;
& lt; pre & gt; } & lt; / pre & gt ;

En este punto de nuestra discusión, la subclase OverdraftAccount no ha anulado este método.

( Nota : Para otra discusión usando esta cuenta y clases OverdraftAccount, vea cómo una subclase puede tratarse como una superclase).

Let & amp; apos; s crea una instancia en cada una de las clases Cuenta y Sobreborrador de Cuenta:

& lt; pre / & gt; & lt; pre & gt; Cuenta bobsAccount = nueva Cuenta (10); & lt; / pre & gt ;
& lt; br & gt ;
& lt; pre & gt; bobsAccount.depositMoney (50); & lt; / pre & gt ;
& lt; br & gt ;
& lt; pre & gt; OverdraftAccount jimsAccount = new OverdraftAccount (15.05,500,0.05); & lt; / pre & gt ;
& lt; br & gt ;
& lt; pre & gt; jimsAccount.depositMoney (50); & lt; / pre & gt ;
& lt; br & gt ;
& lt; pre & gt; // crear una matriz de objetos de cuenta & lt; / pre & gt ;
& lt; br & gt ;
& lt; pre & gt; // podemos incluir jimsAccount porque nosotros & lt; / pre & gt ;
& lt; br & gt ;
& lt; pre & gt; // solo quiere tratarlo como un objeto de cuenta & lt; / pre & gt ;
& lt; br & gt ;
& lt; pre & gt; Cuentas [] cuentas = {bobsAccount, jimsAccount}; & lt; / pre & gt ;
& lt; br & gt ;
& lt; br & gt ;
& lt; pre & gt; // para cada cuenta en la matriz, muestre el saldo & lt; / pre & gt ;
& lt; br & gt ;
& lt; pre & gt; para (Cuenta a: cuentas) & lt; / pre & gt ;
& lt; br & gt ;
& lt; pre & gt; {& lt; / pre & gt ;
& lt; br & gt ;
& lt; pre & gt; System.out.printf (& amp; quot; El saldo es% .2f% n & amp; quot ;, a.getBalance ()); & lt; / pre & gt ;
& lt; br & gt ;
& lt; pre & gt; } & lt; / pre & gt ;
& lt; br & gt ;
& lt; pre & gt; La salida es: & lt; / pre & gt ;
& lt; br & gt ;
& lt; pre & gt; El saldo es 60.00 & lt; / pre & gt ;
& lt; br & gt ;
& lt; pre & gt; El saldo es 65.05 & lt; / pre & gt ;

Todo parece funcionar como se esperaba, aquí. Pero, ¿qué pasa si OverdraftAccount anula el método getBalance ()?? No hay nada que le impida hacer algo como esto:

& lt; pre / & gt; & lt; pre & gt; clase pública OverdraftAccount extiende la cuenta {& lt; / pre & gt ;
& lt; br & gt ;
& lt; br & gt ;
& lt; pre & gt; sobregiro privado doble Límite; & lt; / pre & gt ;
& lt; br & gt ;
& lt; pre & gt; sobregiro privado doble tarifa; & lt; / pre & gt ;
& lt; br & gt ;
& lt; br & gt ;
& lt; pre & gt; // el resto de la definición de clase no está incluido & lt; / pre & gt ;
& lt; br & gt ;
& lt; br & gt ;
& lt; pre & gt; público doble getBalance () & lt; / pre & gt ;
& lt; br & gt ;
& lt; pre & gt; {& lt; / pre & gt ;
& lt; br & gt ;
& lt; pre & gt; devolver 25.00; & lt; / pre & gt ;
& lt; br & gt ;
& lt; pre & gt; } & lt; / pre & gt ;
& lt; br & gt ;
& lt; pre & gt; } & lt; / pre & gt ;

Si el código de ejemplo anterior se ejecuta nuevamente, la salida será diferente porque el comportamiento thegetBalance () en la clase OverdraftAccount se llama para jimsAccount:

& lt; pre / & gt; & lt; pre & gt; La salida es: & lt; / pre & gt ;
& lt; br & gt ;
& lt; pre & gt; El saldo es 60.00 & lt; / pre & gt ;
& lt; br & gt ;
& lt; pre & gt; El saldo es 25.00 & lt; / pre & gt ;

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 subclasificación 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 de cuerda, siempre se comportará como una cuerda.

Cómo prevenir la herencia

Para evitar que se extienda una clase, la declaración de clase debe decir explícitamente que no se puede heredar. Esto se logra mediante el uso de & amp; quot; final & amp; quot; palabra clave:

& lt; pre / & gt; & lt; pre & gt; cuenta de clase final pública {& lt; / pre & gt ;
& lt; br & gt ;
& lt; br & gt ;
& lt; pre & gt; } & lt; / pre & gt ;

Esto significa que la clase Cuenta 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 por una subclase. Por ejemplo, OverdraftAccount todavía podría ser una subclase de Cuenta, pero se debe evitar que anule el método getBalance ().

En este caso, use & amp; quot; final & amp; quot; palabra clave en la declaración del método:

& lt; pre / & gt; & lt; pre & gt; cuenta de clase pública {& lt; / pre & gt ;
& lt; br & gt ;
& lt; br & gt ;
& lt; pre & gt; doble saldo privado; & lt; / pre & gt ;
& lt; br & gt ;
& lt; br & gt ;
& lt; pre & gt; // el resto de la definición de clase no está incluido & lt; / pre & gt ;
& lt; br & gt ;
& lt; br & gt ;
& lt; pre & gt; público final doble getBalance () & lt; / pre & gt ;
& lt; br & gt ;
& lt; pre & gt; {& lt; / pre & gt ;
& lt; br & gt ;
& lt; pre & gt; devolver este saldo; & lt; / pre & gt ;
& lt; br & gt ;
& lt; pre & gt; } & lt; / pre & gt ;
& lt; br & gt ;
& lt; pre & gt; } & lt; / pre & gt ;

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á como lo pretendía el programador original.

& lt; / br & gt ;
& lt; / br & gt ;
& lt; / br & gt ;
& lt; / br & gt ;
& lt; / br & gt ;
& lt; / br & gt ;
& lt; / br & gt ;
& lt; / br & gt ;
& lt; / br & gt ;
& lt; / br & gt ;
& lt; / br & gt ;
& lt; / br & gt ;
& lt; / br & gt ;
& lt; / br & gt ;
& lt; / br & gt ;
& lt; / br & gt ;
& lt; / br & gt ;
& lt; / br & gt ;
& lt; / br & gt ;
& lt; / br & gt ;
& lt; / br & gt ;
& lt; / br & gt ;
& lt; / br & gt ;
& lt; / br & gt ;
& lt; / br & gt ;
& lt; / br & gt ;
& lt; / br & gt ;
& lt; / br & gt ;
& lt; / br & gt ;
& lt; / br & gt ;
& lt; / br & gt ;
& lt; / br & gt ;
& lt; / br & gt ;
& lt; / br & gt ;
& lt; / br & gt ;
& lt; / br & gt ;
& lt; / br & gt ;
& lt; / br & gt ;
& lt; / br & gt ;
& lt; / br & gt ;
& lt; / br & gt ;
& lt; / br & gt ;
& lt; / br & gt ;
& lt; / br & gt ;
& amp; # x203A; Informática

Dejar respuesta

Please enter your comment!
Please enter your name here

FOLLOW US

Related Stories