În timp ce unul dintre Java punctele forte este conceptul de moștenire, în care unul clasă poate deriva de la altul, uneori este de dorit să preveniți moștenirea de către o altă clasă. Pentru a preveni moștenirea, utilizați cuvântul cheie „final” atunci când creați clasa.
De exemplu, dacă o clasă este probabil să fie utilizată de alți programatori, este posibil să doriți să preveniți moștenirea dacă orice subclase create ar putea cauza probleme. Un exemplu tipic este Clasa de coarde. Dacă am fi dorit să creăm o subclasă String:
public class MyString extinde String {
}
Ne-am confrunta cu această eroare:
nu poate moșteni de la java.lang final. Şir
Designerii clasei String și-au dat seama că nu este un candidat pentru moștenire și au împiedicat extinderea acesteia.
De ce să prevină moștenirea?
Motivul principal pentru a preveni moştenire înseamnă să te asiguri că modul în care se comportă o clasă nu este corupt de o subclasă.
Să presupunem că avem un Cont de clasă și o subclasă care îl extinde, OverdraftAccount. Contul clasei are o metodă getBalance ():
public dublu getBalance ()
{
returnează acest.balanț;
}
În acest moment al discuției noastre, subclasa OverdraftAccount nu a înlocuit această metodă.
(Notă: Pentru o altă discuție folosind acest cont și clasele OverdraftAccount, vedeți cum a subclasa poate fi tratată ca o superclasă).
Haideți să creăm o instanță pentru fiecare clasă Cont și OverdraftAccount:
Cont bobsAccount = Cont nou (10);
bobsAccount.depositMoney (50);
OverdraftAccount jimsAccount = new OverdraftAccount (15,05,500,0,05);
jimsAccount.depositMoney (50);
// creați o serie de obiecte Cont
// putem include jimsAccount pentru că noi
// doresc doar să-l trateze ca pe un obiect de cont
Cont [] conturi = {bobsAccount, jimsAccount};
// pentru fiecare cont din tablou, afișați soldul
pentru (Contul: conturi)
{
System.out.printf ("Soldul este% .2f% n", a.getBalance ());
}
Produsul este:
Soldul este de 60,00
Soldul este de 65,05
Totul pare să funcționeze așa cum era de așteptat, aici. Dar dacă OverdraftAccount înlocuiește metoda getBalance ()? Nu există nimic care să-l împiedice să facă așa ceva:
public class OverdraftAccount extinde contul {
overdraft dublu privatLimit;
overdraft dublu privatFee;
// restul definiției clasei nu este inclus
public dublu getBalance ()
{
retur 25,00;
}
}
Dacă exemplul de mai sus este executat din nou, ieșirea va fi diferită, deoarece comportamentul thegetBalance () din clasa OverdraftAccount este apelat la jimsAccount:
Produsul este:
Soldul este de 60,00
Soldul este de 25,00
Din păcate, subclasa OverdraftAccount o va face nu furnizați soldul corect deoarece am deteriorat comportamentul clasei de cont prin moștenire.
Dacă proiectați o clasă care să fie utilizată de alți programatori, luați în considerare întotdeauna implicațiile eventualelor subclase. Acesta este motivul pentru care clasa String nu poate fi extinsă. Este extrem de important ca programatorii să știe că atunci când creează un obiect String, se va comporta întotdeauna ca o String.
Cum să preveniți moștenirea
Pentru a opri extinderea unei clase, declarația de clasă trebuie să spună explicit că nu poate fi moștenită. Acest lucru este realizat folosind cuvântul cheie „final”:
cont public final de clasă {
}
Aceasta înseamnă că clasa Account nu poate fi o superclasă, iar clasa OverdraftAccount nu mai poate fi subclasa sa.
Uneori, poate doriți să limitați doar anumite comportamente ale unei superclase pentru a evita corupția din partea unei subclase. De exemplu, OverdraftAccount ar putea fi încă o subclasă de Cont, dar ar trebui împiedicat să supraestimeze metoda getBalance ().
În acest caz, utilizați cuvântul cheie „final” din declarația metodei:
cont public de clasă {
sold dublu privat;
// restul definiției clasei nu este inclus
public final dublu getBalance ()
{
returnează acest.balanț;
}
}
Observați cum cuvântul cheie final nu este utilizat în definiția clasei. Se pot crea subclase de cont, dar nu mai pot trece peste metoda getBalance (). Orice cod care apelează această metodă poate fi sigur că va funcționa așa cum intenționează programatorul inițial.