Използване на ключовата дума Final с наследяване в Java

click fraud protection

Докато един от на Java силните страни е концепцията за наследство, в която една клас може да произлиза от друг, понякога е желателно да се предотврати наследяването от друг клас. За да предотвратите наследяването, използвайте ключовата дума "окончателен", когато създавате класа.

Например, ако има вероятност даден клас да бъде използван от други програмисти, може да искате да предотвратите наследяването, ако някой създаден подклас може да причини проблеми. Типичен пример е Клас на струни. Ако искахме да създадем подклас String:

MyString от публичен клас разширява String {
}

Ще бъдем изправени пред тази грешка:

 не може да наследи от крайния java.lang. низ 

Дизайнерите от класа String разбраха, че той не е кандидат за наследство и са му попречили да бъде разширен.

Защо да предотвратяваме наследяването?

Основната причина за предотвратяване наследяване е да се уверите, че начинът, по който се държи класът, не е повреден от подклас.

Да предположим, че имаме акаунт в клас и подклас, който го разширява, OverdraftAccount. Акаунтът в клас има метод getBalance ():

instagram viewer
 публичен двоен getBalance ()

{

 върнете този баланс;

 } 

На този етап в нашата дискусия, подклас OverdraftAccount не е отменил този метод.

(Забележка: За друга дискусия с използването на този акаунт и класове OverdraftAccount, вижте как подклас може да се третира като свръхклас).

Нека създадем екземпляр всеки от класовете Account и OverdraftAccount:

 Акаунт bobsAccount = нов акаунт (10);

 bobsAccount.depositMoney (50);

 OverdraftAccount jimsAccount = нов OverdraftAccount (15.05,500,0.05);

 jimsAccount.depositMoney (50);

 // създаване на масив от обекти на акаунт

 // можем да включим jimsAccount, защото ние 

 // искат само да го третират като обект на акаунт

 Акаунт [] акаунти = {bobsAccount, jimsAccount};


 // за всеки акаунт в масива показва баланса

 за (акаунт a: акаунти)

 {

 System.out.printf ("Балансът е% .2f% n", a.getBalance ());

 }

 Изходът е:

 Балансът е 60,00

 Балансът е 65,05 

Всичко изглежда работи, както се очаква, тук. Но какво става, ако OverdraftAccount отмени метода getBalance ()? Няма нищо, което да му попречи да направи нещо подобно:

 публичен клас OverdraftAccount разширява акаунта {


 частен двоен овърдрафтLimit;

 частен двоен овърдрафтFee;


 // останалата част от дефиницията на класа не е включена


 публичен двоен getBalance ()

 {

 връщане 25.00;

 }

 } 

Ако примерният код по-горе се изпълни отново, изходът ще бъде различен, защото поведението thegetBalance () в класа OverdraftAccount се извиква за jimsAccount:

 Изходът е:

 Балансът е 60,00

 Балансът е 25,00 

За съжаление, подкласът OverdraftAccount ще никога осигурете правилния баланс, защото ние покварихме поведението на класа Акаунт чрез наследяване.

Ако проектирате клас, който да се използва от други програмисти, винаги имайте предвид последиците от всички потенциални подкласове. Това е причината стринг класът да не може да бъде разширен. Изключително важно е програмистите да знаят, че когато създават String обект, той винаги ще се държи като String.

Как да се предотврати наследяването

За да се спре разширяването на клас, декларацията за клас трябва изрично да казва, че не може да бъде наследен. Това се постига чрез използване на ключовата дума "окончателно":

 публичен акаунт за последен клас {


 } 

Това означава, че класът Account не може да бъде свръхклас и класът OverdraftAccount вече не може да бъде негов подклас.

Понякога може да искате да ограничите само определени поведения на свръхклас, за да избегнете корупцията от подклас. Например, OverdraftAccount все още може да бъде подклас на Account, но трябва да се предотврати отмяна на метода getBalance ().

В този случай използвайте „крайната“ ключова дума в декларацията на метода:

 акаунт в публична класа {


 частен двоен баланс;


 // останалата част от дефиницията на класа не е включена


 публичен финален двоен getBalance ()

 {

 върнете този баланс;

 } 

 } 

Забележете как крайната ключова дума не се използва в дефиницията на класа. Подкласовете на акаунта могат да бъдат създадени, но те вече не могат да отменят метода getBalance (). Всеки код, извикващ този метод, може да бъде сигурен, че той ще работи както първоначалният програмист е предвидил.

instagram story viewer