Come prevenire l'ereditarietà in Java usando la parola chiave Final

Mentre uno dei punti di forza di Java è il concetto di eredità, in cui una classe può derivare da un'altra, a volte è desiderabile impedire l'ereditarietà 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 è la classe String. Se volessimo creare una sottoclasse String:

public class MyString estende String 

Saremmo di fronte a questo errore:

 impossibile ereditare da java.lang.String finale 

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 impedire l'ereditarietà è 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 ():

 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 che utilizza queste classi Account e OverdraftAccount, vedere come una 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é ilIl comportamento getBalance () nella classe OverdraftAccount viene chiamato per jimsAccount: