Наследование. Преимущество наследования

Открыта

— Привет, Амиго! Сейчас будет одна тема, которой, я думаю, ты будешь частенько пользоваться. Это – наследование.

Программирование, для несведущих, неотличимо от магии. Поэтому начну с такой интересной аналогии…

Предположим, что ты волшебник и хочешь создать летающую лошадь. С одной стороны, ты бы мог попробовать наколдовать пегаса. Но т.к. пегасов в природе не существует, это будет очень непросто. Придется очень много делать самому. Куда проще взять лошадь и приколдовать ей крылья.

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

В программировании такой процесс называется «наследование». Предположим тебе нужно написать очень сложный класс. Писать с нуля долго, потом еще долго все тестировать и искать ошибки. Зачем идти самым сложным путем? Лучше поискать – а нет ли уже такого класса?

Предположим, ты нашел класс, который своими методами реализует 80% нужной тебе функциональности. Ты можешь просто скопировать его код в свой класс. Но у такого решения есть несколько минусов:

1) Найденный класс уже может быть скомпилирован в байт-код, а доступа к его исходному коду у тебя нет.

2) Исходный код класса есть, но ты работаешь в компании, которую могут засудить на пару миллиардов за использование даже 6 строчек чужого кода. А потом она засудит тебя.

3) Ненужное дублирование большого объема кода. Кроме того, если автор чужого класса найдет в нем ошибку и исправит ее, у тебя эта ошибка останется.

Есть решение потоньше, и без необходимости получать легальный доступ к коду оригинального класса. В Java ты можешь просто объявить тот класс родителем твоего класса. Это будет эквивалентно тому, что ты добавил код того класса в код своего. В твоем классе появятся все данные и все методы класса-родителя. Например, можно делать так: наследуемся от «лошади», добавляем «крылья» — получаем «пегаса»

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

— Очень интересно, продолжай.

— Наследование можно использовать и для других целей. Допустим, у тебя есть десять классов, которые очень похожи, имеют совпадающие данные и методы. Ты можешь создать специальный базовый класс, вынести эти данные (и работающие с ними методы) в этот базовый класс и объявить те десять классов его наследниками. Т.е. указать в каждом классе, что у него есть класс-родитель – данный базовый класс.

Также как преимущества абстракции раскрываются только рядом с инкапсуляцией, так и преимущества наследования гораздо сильнее при использовании полиморфизма. Но о нем я расскажу завтра. Сегодня же мы рассмотрим несколько примеров использования наследования.

Предположим, мы пишем программу, которая играет в шахматы с пользователем, тогда нам понадобятся классы для фигур. Какие бы ты предложил классы, Амиго?

— Король, Ферзь, Слон, Конь, Ладья и Пешка.

— Отлично. Ничего не упустил.

— А какие бы данные ты предложил хранить в этих классах?

— Координаты x и y, а также ее ценность (worth). Ведь некоторые фигуры ценнее других.

— А в чем отличия этих классов?

— Отличия в том, как они ходят, фигуры. В поведении.

— Да. Вот как можно было бы описать их в виде классов

class King
{
int x;
int y;
int worth;
void kingMove()
{
//код, решающий,
//как пойдет король
}
}
class Queen
{
int x;
int y;
int worth;
void queenMove()
{
//код, решающий,
//как пойдет ферзь
}
}
class Rook
{
int x;
int y;
int worth;
void rookMove()
{
//код, решающий,
//как пойдет ладья
}
}
class Knight
{
int x;
int y;
int worth;
void knightMove()
{
//код, решающий,
//как пойдет конь
}
}
class Bishop
{
int x;
int y;
int worth;
void bishopMove()
{
//код, решающий,
//как пойдет слон
}
}
class Pawn
{
int x;
int y;
int worth;
void pawnMove()
{
//код, решающий,
//как пойдет пешка
}
}
3
Задача
Java Core,  1 уровень,  5 лекция
Недоступна
Набираем код Ӏ Java Core: 1 уровень, 5 лекция
Java Core: 1 уровень, 5 лекция. Иногда думать не надо, строчить надо! Как ни парадоксально звучит, порой пальцы «запоминают» лучше, чем сознание. Вот почему во время обучения в секретном центре JavaRush вы иногда встречаете задания на набор кода. Набирая код, вы привыкаете к синтаксису и зарабатываете немного материи. А ещё — боретесь с ленью.

— Да, именно так я бы и написал.

— А вот, как можно было бы сократить код с помощью наследования. Мы могли бы вынести одинаковые методы и данные в общий класс. Назовем его ChessItem. Объекты класса ChessItem не имеет смысла создавать, так как ему не соответствует ни одна шахматная фигура, но от него было бы много пользы:

class King extends ChessItem
{
void kingMove()
{
//код, решающий,
//как пойдет король
}
}
class Queen extends ChessItem
{
void queenMove()
{
//код, решающий,
//как пойдет ферзь
}
}
class Rook extends ChessItem
{
void rookMove()
{
//код, решающий,
//как пойдет ладья
}
}
class ChessItem
{
int x;
int y;
int worth;
}
class Knight extends ChessItem
{
void knightMove()
{
//код, решающий,
//как пойдет конь
}
}
class Bishop extends ChessItem
{
void bishopMove()
{
//код, решающий,
//как пойдет слон
}
}
class Pawn extends ChessItem
{
void pawnMove()
{
//код, решающий,
//как пойдет пешка
}
}
3
Задача
Java Core,  1 уровень,  5 лекция
Недоступна
Набираем больше кода Ӏ Java Core: 1 уровень, 5 лекция
Java Core: 1 уровень, 5 лекция. Внимание! Объявляется набор кода на JavaRush. Для этого включите режим повышенной внимательности, расслабьте пальцы, читайте код и… набирайте его в соответствующем окошке. Набор кода — вовсе не бесполезное занятие, как может показаться на первый взгляд: благодаря ему новичок привыкает к синтаксису и запоминает его (современные IDE редко дают ему это сделать).

— Как интересно.

— Именно! Особенно много преимуществ мы получаем, когда в проекте тысячи различных объектов и сотни классов. Тогда правильно подобранными классами можно не только существенно упростить логику, но и сократить код в десятки раз.

— А что нужно чтобы унаследовать какой-то класс?

— Для этого после объявления нашего класса нужно указать ключевое слово extends и написать имя родительского класса. Унаследоваться можно только от одного класса.

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

На картинке мы видим «корову», унаследованную от «свиньи». «Свинья» унаследована от «курицы», «курица» от «яйца». Только один родитель! Такое наследование не всегда логично. Но если есть только свинья, а очень нужна корова, программист зачастую не может устоять перед желанием сделать «корову» из «свиньи».

— А если мне хочется унаследоваться от двух классов. Можно же что-то сделать?!

— Почти ничего. Множественного наследования классов в Java нет: класс может иметь только одного класса-родителя. Но есть множественное наследование интерфейсов. Это немного снижает остроту проблемы.

— Ясно. А что такое интерфейс?

— Про интерфейсы я расскажу тебе завтра, а пока давай продолжим разбираться с наследованием.

Комментарии (116)
  • популярные
  • новые
  • старые
Для того, чтобы оставить комментарий вы должны авторизоваться
Drew16 уровень, Москва
1 мая, 10:23
А я думал, что крылья к коню - это композиция. Тут наследование🤔
Константин17 уровень, Санкт-Петербург
15 апреля, 17:25
А теперь, Амиго, я расскажу тебе о наследовании в Pascal....😁😂🤣
Андрей12 уровень, Самара
20 апреля, 13:24
- Ясно.
Глеб16 уровень
11 апреля, 03:25
>Почти ничего. Множественного наследования классов в Java нет Что интересно, здесь же, на JavaRush, есть статья о множественном наследовании
Александр Иванов13 уровень, Москва
13 апреля, 00:05
именно )) и там как раз написано, что множественное наследование классов не поддерживается)) множественное возможно только для интерфейсов, что как раз укладывается в слова "почти ничего"
Глеб16 уровень
11 апреля, 03:12
"Исходный код класса есть, но ты работаешь в компании, которую могут засудить на пару миллиардов за использование даже 6 строчек чужого кода. А потом она засудит тебя." - А вот насчет этого поподробнее, пожалуйста. Этак если это правда, то в коммерческом программировании для полной безопасности надо все с нуля писать. ... И ещё, насколько я понимаю, чтобы такой судебное разбирательство возникло, нужно чтобы: 1. Украденный код является частью платного приложения (а иначе какой вред от того, что код украден?) 2. ... но несмотря на это, код может быть просмотрен по меньшей мере купившими приложение. А смысл тогда в "упаковке" приложений?
progdamn23 уровень, Санкт-Петербург
29 февраля, 16:30
"Исходный код класса есть, но ты работаешь в компании, которую могут засудить на пару миллиардов за использование даже 6 строчек чужого кода. А потом она засудит тебя." - oracle как раз судилась с google из-за использования нескольких строчек java кода).
Руслан Музыка16 уровень, Dergachi
8 марта, 13:24
видимо ребята (те, кто писал или же воровал эти строки) плохо учились в универе, ибо самое первое правило спизженого кода - меняй названия переменных и методов)
Глеб16 уровень
11 апреля, 03:14
А как доказать, что это не совпадение? Компьютеры будут изъяты судебной экспертизой и будут каким-то образом искать логирование действий на компьютере, если таковой механизм есть?
Alexander Kolesnik13 уровень, Москва
6 мая, 19:10
пригласят эксперта и спросят его мнение
Radik Gismatullin22 уровень, Казань
13 февраля, 18:37
В класс ChessItem я бы добавил move().
Николай Б17 уровень, Минск
27 февраля, 04:06
я не шахматитст. Но каждый тип фигуры ходит по-своему. Смысл в родительском классе иметь мув? или переписывать его под каждую фигуру? Я не понимаю, но программирование не изучал, объяните пж
Radik Gismatullin22 уровень, Казань
2 марта, 19:38
Согласно принципу абстракции, умение делать ход - это общее важное свойство всех фигур без исключения. А используя полиморфизм, каждая фигура уже реализует метод move() согласно правилам шахмат. Будет логично и единообразно, как мне кажется.
Николай Б17 уровень, Минск
2 марта, 20:02
Спасибо за ответ.. Сам дальше по курсу понял смысл Вашего первого поста. Удачи нам в учебе :)
Radik Gismatullin22 уровень, Казань
2 марта, 20:31
Взаимно, Николай, удачи нам)
Руслан Музыка16 уровень, Dergachi
8 марта, 13:33
если я правильно понимаю, то в суперклассе мы просто пишем метод move(), а в подклассах уже переопределяем его под каждую фигуру?
Radik Gismatullin22 уровень, Казань
14 марта, 20:30
Да, каждая фигура ходит по своему
Kravchynskiy Volodymyr19 уровень, Житомир
6 февраля, 11:32
конспект ..... Существует простое правило, позволяющее определить, стоит ли в конкретной ситуации применять наследование или нет. Если между объектами существует отношение "является" , то каждый объект подкласса является объектом суперкласса.
Алексей16 уровень, Казань
6 февраля, 08:03
Идем дальше...
Никита Сычев24 уровень, Санкт-Петербург
28 января, 20:25
НАЙДЕНО РЕШЕНИЕ!!!!!!!!!!!!!!!!!!!!!!!! правая кнопка мыши копировать. и правая кнопка мыши вставить!!!!!!!!! и не тратить время на переписывание
Никита Сычев24 уровень, Санкт-Петербург
28 января, 20:27
да забыл Ctrl+a)) вначале
Justinian41 уровень, Киев
1 февраля, 23:22
можно разбрасывать камни, но потом обязательно придет время их собирать :) И эта "экономия" время потом обернется такой потерей времени, что ого-го. Но у каждого из нас свои грабли :) Дело житейское
Павел Краснов22 уровень, Архангельск
27 января, 06:16
А как же полиморфизм? какого делать каждой фигуре свой moveXXX. согласно идеологии должен быть move() у ChessItem и переопределен в классах фигур!