„Здравей, Амиго! Ето една тема, която мисля, че ще използваш много. Говоря за наследство.

За непосветените програмирането е като магия. Така че нека започна с една аналогия...

Да предположим, че сте магьосник, който иска да създаде летящ кон. Можеш да опиташ да измислиш Пегас. Но тъй като летящите коне не се срещат естествено, ще ви е наистина трудно. Щеше да имаш много работа. Би било много по-лесно да започнете с кон и да призовете няколко крила.

Наследство.  Предимства на наследството - 1

В програмирането ние наричаме този процес „наследяване“ . Да предположим, че трябва да напишете много сложен клас. Бихте могли да прекарате дълго време в писане на code от нулата и след това да извършите продължително тестване, за да откриете грешки. Но защо да го правим по трудния начин? По-добре е да се огледате и да видите дали класът, който търсите, вече съществува?

Да приемем, че намерите клас, който изпълнява 80% от функционалността, от която се нуждаете. Можете просто да копирате неговия code във вашия клас. Но това би имало няколко недостатъка:

1) Класът, който намирате, може вече да е компorран в byte code. Възможно е да нямате достъп до неговия изходен code.

2) Може да имате изходния code за класа, но също така да работите в компания, която може да бъде съдена за няколко мorарда, ако използвате дори 6 реда от codeа на някой друг. И тогава ще те съдят.

3) Това води до ненужно дублиране на много code. И ако авторът на другия клас открие грешка и я поправи, вие все още имате грешката.

Има по-елегантно решение, което не изисква получаване на законно разрешение за codeа на оригиналния клас. В Java можете просто да декларирате другия клас като родител на вашия клас. Това е еквивалентно на добавяне на codeа на този клас към вашия собствен клас. Всички данни и методи на родителския клас ще се появят във вашия клас. Например, можете да наследите от «кон», да добавите «крила» и да получите «Пегас».

Наследство.  Предимства на наследството - 2

"Много интересно. Моля, продължете."

„Наследяването има и други applications. Да предположим, че имате десет класа, които са много сходни. Те имат съвпадащи данни и методи. Можете да създадете специален базов клас , да преместите данните (и свързаните методи) в базовия клас и да имате тези десет класа наследяват от него. С други думи, за всеки клас посочвате, че има родителски клас, известен също като базов клас."

"Точно Howто предимствата на абстракцията се разкриват истински само във връзка с капсулирането, предимствата на наследяването се увеличават от полиморфизма. Но ще ви разкажа за това утре. Днес нека разгледаме няколко примера за наследяване."

„Да предположим, че пишем шахматна програма. Ще ни трябват класове за шахматните фигури. Кои класове бихте предложor, Амиго?“

"Поп, Дама, Епископ, Кон, Топ и Пешка."

"Много добре. Нищо не си пропуснал."

„И Howви данни бихте предложor да съхранявате в тези класове?“

„Позиция на борда на всяка фигура (x и y) и стойност. В крайна сметка някои фигури са по-ценни от други.“

— И Howви са разликите между тези класове?

"Те се различават по начина, по който движат фигурите. По поведението си."

„Да. Можете да ги дефинирате като класове като това:“

class King
{
int x;
int y;
int worth;
void kingMove()
{
//code that defines,
//how the king moves
}
}
class Queen
{
int x;
int y;
int worth;
void queenMove()
{
//code that defines,
//how the queen moves
}
}
class Rook
{
int x;
int y;
int worth;
void rookMove()
{
//code that defines,
//how the rook moves
}
}
class Knight
{
int x;
int y;
int worth;
void knightMove()
{
//code that defines,
//how the knight moves
}
}
class Bishop
{
int x;
int y;
int worth;
void bishopMove()
{
//code that defines,
//how the bishop moves
}
}
class Pawn
{
int x;
int y;
int worth;
void pawnMove()
{
//code that defines,
//how the pawn moves
}
}

— Да, точно така бих го написал.

„Но вижте How можете да използвате наследяването, за да пишете по-малко code. Можем да преместим идентични методи и данни в общ клас. Нека го наречем ChessItem. Няма смисъл да създаваме обекти ChessItem, тъй като те не съответстват на нито един шахматна фигура. Но класът би бил изключително полезен:"

class King extends ChessItem
{
void kingMove()
{
//code that defines,
//how the king moves
}
}
class Queen extends ChessItem
{
void queenMove()
{
//code that defines,
//how the queen moves
}
}
class Rook extends ChessItem
{
void rookMove()
{
//code that defines,
//how the rook moves
}
}
class ChessItem
{
int x;
int y;
int worth;
}
class Knight extends ChessItem
{
void knightMove()
{
//code that defines,
//how the knight moves
}
}
class Bishop extends ChessItem
{
void bishopMove()
{
//code that defines,
//how the bishop moves
}
}
class Pawn extends ChessItem
{
void pawnMove()
{
//code that defines,
//how the pawn moves
}
}

"Колко интересно!"

"Абсолютно! Ползата е особено голяма в проекти, съдържащи хиляди различни обекти и стотици класове. В този случай правилно избраните класове могат не само значително да опростят логиката, но и да намалят необходимия code с фактор десет."

„И така, Howво трябва да направите, за да наследите клас?“

„След като декларираме клас, използваме ключовата дума„ extends “, последвана от името на родителския клас. Можете да наследявате само от един клас.

Наследство.  Предимства на наследството - 3

Картината показва "крава", която е наследила от "прасе". «Прасето» наследява от «пилето», а «пилето» наследява от «яйцето». Всеки клас има само един родител! Такова наследяване не винаги е логично. Ако имате само прасе, но наистина имате нужда от крава, програмистите често не могат да устоят на желанието да направят „крава“ от „прасето“.

"Но Howво ще стане, ако искам да наследя от два класа? Мога ли да направя нещо?!"

„Всъщност не. Java класовете не поддържат множествено наследяване на изпълнение: един клас може да има само един родителски клас. Но има множествено наследяване на тип, което означава, че един клас може да реализира повече от един интерфейс. Това леко смекчава проблема. "

"Разбирам. И Howво е интерфейс?"

„Ще ви разкажа за интерфейсите утре. Засега нека продължим да се задълбочаваме в наследството.“