Utilizzo della parola chiave Final con ereditarietà in Java

Mentre uno di Java punti di forza è il concetto di eredità, in cui uno classe può derivare da un altro, a volte è desiderabile impedire l'eredità di un'altra classe. Per evitare l'ereditarietà, utilizzare la parola chiave "final" durante la creazione della classe.

Ad esempio, se è probabile che una classe venga utilizzata da altri programmatori, è possibile che si desideri impedire l'ereditarietà se eventuali sottoclassi create potrebbero causare problemi. Un esempio tipico è il Classe di stringa. Se volessimo creare una sottoclasse String:

public class MyString estende String {
}

Saremmo di fronte a questo errore:

 impossibile ereditare da java.lang finale. Corda 

I progettisti della classe String si resero conto che non era un candidato per l'ereditarietà e ne hanno impedito l'estensione.

Perché prevenire l'ereditarietà?

Il motivo principale per prevenire eredità è assicurarsi che il modo in cui una classe si comporta non sia corrotto da una sottoclasse.

Supponiamo di avere un account di classe e una sottoclasse che lo estenda, OverdraftAccount. L'account di classe ha un metodo getBalance ():

instagram viewer

 pubblico doppio getBalance ()

{

 restituire this.balance;

 } 

A questo punto della nostra discussione, la sottoclasse OverdraftAccount non ha ignorato questo metodo.

(Nota: Per un'altra discussione sull'utilizzo di questo account e delle classi di conto corrente, vedere come a la sottoclasse può essere trattata come una superclasse).

Creiamo un'istanza per ciascuna delle classi Account e OverdraftAccount:

 Account bobsAccount = new Account (10);

 bobsAccount.depositMoney (50);

 OverdraftAccount jimsAccount = new OverdraftAccount (15.05.500,0,05);

 jimsAccount.depositMoney (50);

 // crea una matrice di oggetti Account

 // possiamo includere jimsAccount perché noi 

 // vuole solo trattarlo come un oggetto Account

 Account [] account = {bobsAccount, jimsAccount};


 // per ciascun account dell'array, visualizza il saldo

 per (Account a: account)

 {

 System.out.printf ("Il saldo è% .2f% n", a.getBalance ());

 }

 L'output è:

 Il saldo è di 60,00

 Il saldo è 65,05 

Qui tutto sembra funzionare come previsto. Ma cosa succede se OverdraftAccount sovrascrive il metodo getBalance ()? Non c'è nulla che gli impedisca di fare qualcosa del genere:

 classe pubblica OverdraftAccount estende l'account {


 double overdraftLimit privato;

 double overdraftFee privato;


 // il resto della definizione di classe non è incluso


 pubblico doppio getBalance ()

 {

 ritorno 25,00;

 }

 } 

Se il codice di esempio sopra viene eseguito di nuovo, l'output sarà diverso perché il comportamento thegetBalance () nella classe OverdraftAccount viene chiamato per jimsAccount:

 L'output è:

 Il saldo è di 60,00

 Il saldo è di 25,00 

Sfortunatamente, la sottoclasse OverdraftAccount lo farà mai fornire il saldo corretto perché abbiamo corrotto il comportamento della classe Account tramite ereditarietà.

Se si progetta una classe che verrà utilizzata da altri programmatori, considerare sempre le implicazioni di eventuali sottoclassi potenziali. Questo è il motivo per cui la classe String non può essere estesa. È estremamente importante che i programmatori sappiano che quando creano un oggetto String, si comporterà sempre come una stringa.

Come prevenire l'ereditarietà

Per impedire l'estensione di una classe, la dichiarazione di classe deve dire esplicitamente che non può essere ereditata. Ciò si ottiene utilizzando la parola chiave "finale":

 Conto pubblico della classe finale {


 } 

Ciò significa che la classe Account non può essere una superclasse e la classe OverdraftAccount non può più essere la sua sottoclasse.

A volte, potresti voler limitare solo alcuni comportamenti di una superclasse per evitare la corruzione di una sottoclasse. Ad esempio, OverdraftAccount potrebbe ancora essere una sottoclasse di Account, ma dovrebbe essere impedito di sovrascrivere il metodo getBalance ().

In questo caso, utilizzare la parola chiave "finale" nella dichiarazione del metodo:

 Account di classe pubblica {


 doppio saldo privato;


 // il resto della definizione di classe non è incluso


 doppio finale pubblico getBalance ()

 {

 restituire this.balance;

 } 

 } 

Nota come la parola chiave finale non viene utilizzata nella definizione della classe. È possibile creare sottoclassi di account, ma non possono più sovrascrivere il metodo getBalance (). Qualsiasi codice che chiama quel metodo può essere sicuro che funzionerà come previsto dal programmatore originale.

instagram story viewer