Абстрактные классы

Открыта

— Привет, Амиго! Новая интересная тема.

— Да сегодня просто день интересных тем!!

— Спасибо!

— Да не за что.

— Помнишь ситуацию, когда мы ввели базовый класс ChessItem для упрощения всех классов шахматных фигур?

— Да.

— Теперь представь, что у каждой фигуры есть метод, который занимается ее отрисовкой на экране. Вызываешь метод, и фигура сама себя рисует в своих текущих координатах. Удобно было бы вынести этот метод в базовый класс?

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

Пример
class ChessBoard
{
  public void drawAllChessItems()
  {
  //добавляем фигуры в список
  ArrayList items = new ArrayList();
  items.add(new King());
  items.add(new Queen());
  items.add(new Bishop());

  //рисуем их независимо от их типа.
  for (ChessItem item: items)
  {
   item.draw();
  }
 }
}

— Молодец. Именно так. А что бы отрисовал на экране метод draw самого класса ChessItem?

— Не знаю. Такой фигуры ведь в шахматах нет. Значит, и изображения у нее нет.

— Именно. Более того, создавать объекты типа ChessItem – не имеет смысла. Это не фигура из шахмат, всего лишь абстракция — класс, который мы сделали для удобства. Так работает абстракция из ООП: мы вынесли важные (общие для всех фигур) данные и методы в базовый класс, а их различия оставили в их классах.

Для такого случая в Java есть специальный тип классов – абстрактные классы. Вот три вещи, которые стоит помнить об абстрактных классах.

1) Абстрактный класс может содержать объявление метода без его реализации. Такой метод называется абстрактным.

Пример
public abstract class ChessItem
{
 public int x, y; //координаты
 private int value; // «ценность» фигуры

 public int getValue() //обычный метод, возвращает значение value
 {
   return value;
 }

 public abstract void draw(); //абстрактный метод. Реализация отсутствует.

}
14
Задача
Java Core,  2 уровень,  5 лекция
Недоступна
Набираем код
Иногда думать не надо, строчить надо! Как ни парадоксально звучит, порой пальцы «запоминают» лучше, чем сознание. Вот почему во время обучения в секретном центре JavaRush вы иногда встречаете задания на набор кода. Набирая код, вы привыкаете к синтаксису и зарабатываете немного материи. А ещё — боретесь с ленью.

2) Абстрактный метод помечается специальным ключевым словом abstract.

Если в классе есть хоть один абстрактный метод, класс тоже помечается ключевым словом abstract.

3) Создавать объекты абстрактного класса нельзя. Такой код просто не скомпилирует.

Код на Java Описание
ChessItem item = new ChessItem();
item.draw();
Этот код не скомпилируется
ChessItem item = new Queen();
item.draw();
А так можно.

4) Если ты наследовал свой класс от абстрактного класса, то нужно переопределить все унаследованные абстрактные методы — написать для них реализацию. Иначе такой класс тоже придется объявить абстрактным. Если в классе есть хотя-бы один нереализованный метод, объявленный прямо в нем или унаследованный от класса-родителя, то класс считается абстрактным.

— А зачем это все нужно? Зачем нужны абстрактные классы? Разве нельзя вместо них использовать обычные? А вместо абстрактных методов просто писать две скобочки в качестве тела метода — {} ?

— Можно. Но эти ограничения сродни модификатору private. Мы специально запрещали с помощью private прямой доступ к данным, чтобы другие программисты и их классы пользовались только написанными нами public-методами.

То же и с абстрактным классом. Тот, кто написал этот класс, не хочет, чтобы создавались его объекты. Наоборот, он рассчитывает на то, чтобы от его абстрактного класса наследовались и переопределяли абстрактные методы.

— Все равно не понятно, зачем усложнять себе жизнь?

— Преимущество этого проявляется в больших проектах. Чем больше классов, тем чётче приходится очерчивать их роли. Ты увидишь преимущество этого, и уже в ближайшем будущем. Все через это проходят.

Комментарии (48)
  • популярные
  • новые
  • старые
Для того, чтобы оставить комментарий вы должны авторизоваться
Даниил24 уровень
16 декабря 2018, 10:37
Вот понять не могу одного. Куча комментариев под лекциями от людей которые оставили их не одну неделю, а то и месяц назад и с тех пор прошли всего несколько уровней. И все они останавливаются в диапазоне 17-24 уровней. Почему так?! Люди, куда вы деваетесь? Может со временем понимаешь что тут ловить нечего? Я в это могу поверить, но только в случае если человек готовый программист, которому просто нужно было познакомиться с синтаксисом. Кто мне объяснит почему так случается?
Сергей14 уровень
20 декабря 2018, 13:42
Может на работу выходят?? И там начинается такой ДжаваРааааш... Только не за "черную материю", а за реальные деньги) Ну или увольнение)
Даниил24 уровень
20 декабря 2018, 18:24
Ну вот в том то и вопрос: если человек с нулевыми знаниями (в программировании вообще, как я) дошёл до примерно 20 уровня тут, врядли его куда-то возьмут. Ну небось люди или были с базой, ознакомились с нюансами для языка и пошли рубить бабло, либо я чего-то не знаю)))
Сергей14 уровень
21 декабря 2018, 11:10
Не понял логику, почему его не возьмут? Но забегая вперёд, сразу отвечу. Чтобы комфортно и легко дойти до высокого уровня тут, надо быть не только тут (соррян за каламбур). Я, например, прохожу ещё обучение на другом портале, подписываюсь на всякие тесты и движи, смотрю какие-то бесплатные видосы, читаю статьи, книги. Изучая информацию из разных мест в голове складывается более полная картинка и появляется понимание и чувство уверенности, что ты что-то соображаешь и можешь сделать.
Даниил24 уровень
21 декабря 2018, 13:03
Та я тоже больше информации черпаю не с этого ресурса, но логика в состояла том что Я ПРЕДПОЛАГАЮ что если начать обучение с уровнем "не умею на любом языке вывести "Hello World" и выучить более-менее всё что дают до 20 уровня тут (изучая углублённо, не только в маленьких ознакомительных лекциях тут) то врядли можно претендовать на Джуна
Вадим22 уровень, Новосибирск
4 января, 18:54
Думаю на стажировку после 20 уровня можно пойти.
Даниил24 уровень
4 января, 20:25
Стажировку в смысле в какую-то компанию?
Denis Fedotov17 уровень, Москва
5 января, 20:35
а сам то куда пропал?))
Даниил24 уровень
6 января, 11:32
Та куда... Праздники, пьянки, и как-то в кучу себя взять не получается основательно. Да и конец года, начало нового - на работе завал. Но это всё отмазки, сейчас с мыслями собираюст и пробую дальше пахать) Но я ж не бросаю как те о которых я говорил, т. е. совсем?
Юрий18 уровень, Минск
7 января, 20:07
так она видна, только в IDEA, на начальных уровнях было больше 60_000 решений задачи, а сейчас только 20_000 в среднем.
Parsifal18 уровень, Алматы
9 января, 18:57
помоему им не интересно комментит, только отзывчивые отвечают
Denis Filokhin15 уровень
24 января, 16:44
У меня друг прошел до 25. Сказал, что бросил, т.к. по его мнению ничего нового не дают, просто дают более сложные задачи на основе пройденного материала. Так это или нет, постараюсь проверить на личном опыте. Ну и работу нашел )
Даниил24 уровень
24 января, 17:27
Если нашёл работу, то реально смысла тут сидеть уже крайне мало, если на работе делом занимаешься. На счёт того "ничего нового", то скажу так: дошёл до 19 уровня пока (начав с нулевымм знаниями в программировании вообще) и каждое новое задание так или иначе полезно или ОЧЕНЬ полезно.
7 февраля, 13:08
Мне кажется, что имея 17-20 уровней тут, на работу устроиться полноценным разрабом нереально. Разве что на internship либо на курсы в EPAM и т.п. Скорее всего просто забивают, тем более если подписка была на месяц.
Даниил24 уровень
7 февраля, 14:49
Заканчивая 20 уровень я кажется нашёл ответ на свой первый вопрос... Реально дальше идут только те кто не намерен разворачиватся, потому что реально тяжело моментами. И времени всё больше и больше уходит...
Андрей13 уровень, Новосибирск
суббота, 15:30
Дальше на мультитрединг пошёл или в коллекции?
Даниил24 уровень
воскресенье, 08:45
Пошёл по потокам, но советовали к середине квеста пару первых уровней пройти по коллекциям.
Макс20 уровень, Киев
4 ноября 2018, 18:04
АСТРАКТНЫЙ КЛАСС ✔ Может содержать объявление метода без его реализации (абстрактный метод) ✔ Если в классе есть хоть один абстрактный метод, класс тоже помечается ключевым словом abstract ✔ Создавать объекты абстрактного класса нельзя. Но можно создавать переменную типа абстрактного класса и присвоить ей ссылку на объект не абстрактного дочернего класса. Пример ↓
// класс Animal абстрактный, класс Lion не абстрактный и унаследован от Animal
Animal lionFather = new Lion("Папуля");
✔ Класс-наследник абстрактного класса должен переопределять (реализовать) все абстрактные методы. Иначе класс-наследник придётся тоже пометить как абстрактный :(
Andrii Gorshunov31 уровень
15 ноября 2018, 20:53
Абстрактный класс может иметь абстрактные методы (без тела {} или без реализации, иными словами) и может иметь обычные методы (не абстрактные) с готовой реализацией.
Эмир Смагулов17 уровень
7 сентября 2018, 06:31
Объясните дураку пожалуйста, в чем смысл абстрактных классов и интерфейсов, если в итоге при наследовании от них, нужно опять писать все методы пусть даже без модификаторов доступа + расписывать тело
Эмир Смагулов17 уровень
7 сентября 2018, 12:40
Отбой понял уже, для тех, кого мучает этот же вопрос просто идите дальше по курсу, там будет объяснение.
Олег Коньшин16 уровень
31 октября 2018, 07:29
я так понимаю это для наглядности чтобы программист использующий этот код понимал что этот метод будет реализовываться по разному в классах-потомках
Gennadiy14 уровень, Одесса
27 января, 15:28
Наверное, абстрактный класс нужен, чтобы один раз и для всех его потомков описать общие черты, характеристики, поля, методы и т.п., чтобы не делать то же самое для каждого "подкласса". Грубо говоря, создаем т.н. шаблон для классов - потомков.
Skosh17 уровень, Новосибирск
20 июня 2018, 07:34
наконец-то мне что-то непонятно! пойду читать Шилдта...
Сергей Никонов40 уровень, Минск
7 мая 2018, 14:31
Разве в первом примере не нужно параметризовать список? При использовании for-each будет же извлекаться объект типа Object, у которого нет метода draw().
wo0denstars14 уровень, Новосибирск
17 мая 2018, 12:49
извлекается ChessItem
Сергей Никонов40 уровень, Минск
22 мая 2018, 08:58
Окей, объясню на пальцах. Есть у нас треугольники, квадраты и круги. Для начала мы сложим все круги в ведро. Но не в специальное ведро, подписанное "для кругов", а в ведро для всего. Затем достанем все фигуры из ведра (а мы то считаем, что там только круги, хотя это и не гарантировано) и засунем в отверстие для круга. Всё будет хорошо до тех пор, пока мы не достанем квадрат, который был закинут в ведро аутистом Васей. Так вот, Java умнее Васи.
Alena35 уровень, Минск
31 мая 2018, 17:37
Спасибо, если бы не Ваш комментарий, то не обратила бы внимания на шикарную возможность итерации по родительскому классу.
Василий Томский22 уровень, Yakutsk
14 июля 2018, 08:42
Вася не аутист, и вообще, мама говорит: "кто дурак тот сам знает"!
Ivan25 уровень
19 июля 2018, 16:22
Да, в примере, почему то упустили параметризацию списка, по идее должно быть:
ArrayList<ChessItem> items = new ArrayList<ChessItem>();
Поигрался и для себя собрал полностью рабочую версию :) ну и в статье, ссылку на которую давали на прошлой лекции в комментах, пишут следующее: Generics
//плохо
List a = new ArrayList();
//хорошо
List<String> a = new ArrayList<String>();
Всегда старайтесь типизировать ваши коллекции, методы и классы. Это избавляет сразу от 2-х потенциальных проблем: приведение типов и ошибок выполнения. Также назначение таких коллекций легче воспринимать. Особенно часто этим пренебрегают мои американо-индусские коллеги. Если же ваша коллекция должна содержать объекты разных типов — используйте <?>, а еще лучше <? extends someType> тогда зная общий класс/интерфейс для всех объектов вам не придется делать приведение типов и применять оператор instanceOf.
4 августа 2018, 19:44
Сергею лайков наставили, хотя он ничего не разъяснил, а только привёл глупые аналогии. А вам за месяц лайков не поставили, хотя всё чётко расписали. Generics rule! Уважаемые пользователи, а ну-ка лукасов накидали, чтобы полезный комментарий не пропал!!!
Anabiozzze35 уровень, Санкт-Петербург
25 марта 2018, 21:56
Здесь подробно и ясно написано про абстрактные методы, а заодно и про интерфейсы: http://kostin.ws/java/java-abstract-and-interfaces.html
7 сентября 2017, 16:19
Вот три вещи, которые стоит помнить об абстрактных классах. 1) 2) 3) 4) )))))) прям как в армии!
Виталий37 уровень
11 сентября 2017, 16:28
Улыбнуло! )
Roman Karimov16 уровень, Москва
11 сентября 2017, 22:07
0) 1) 2) 3)
Sergio19 уровень
12 сентября 2017, 14:35
Мы же считаем вещи по их числу, а не последнему индексу? :)
Азад Мамедов21 уровень, Самара
15 сентября 2017, 22:28
Это вам не баги искать в коде:) тут мозги нужны чтобы заметить, что вместо 3х пунктов представлены 4:)
Джонни35 уровень
24 октября 2017, 16:06
"0) 1) 2) 3)" твойМассив.length == 4 ;)
Aleksejs14 уровень
5 декабря 2017, 03:48
Мне сразу бросилось в глаза. Подумал что за бред! А еще как принято в программировании считать с нуля, даже если так то всеравно 4 выйдет дойдя до 3. Кароче забил голову сам себе, из=за какого-то парнишки =)
Андрей13 уровень
22 февраля 2018, 15:47
Боже Джонни , они сломали твои мозги , ты это понимаешь Джоннннннннннииииииииииииииииииииииииииииииииииии!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
Артем23 уровень
6 декабря 2018, 18:02
ArrayIndexOutOfBoundsException
Ivana Petrova36 уровень
3 июня 2017, 10:07
Т.е если я правльно понимаю,то все классы унаследованные от ChessItem тоже становятся абстрактными?И при этом мы должны переопределить все методы? Почему бы просто не объявить класс private ?
Даня Кельвич39 уровень, Киев
4 июня 2017, 09:22
Нет, классы унаследованные от ChessItem реализуют все абстрактные методы, поэтому объекты этих классов можно создать. Это все объясняется в Head First Java.
Akira Rokudo20 уровень, Москва
25 июня 2017, 07:07
Добавлю к комментарию Дани-либо реализуют все методы, либо тоже становятся абстрактными. Почему же не объявлять класс как private?это возможно только если он внутренний.(Иначе он будет доступен только для себя, что лишено логики) А смысл внутренних классов в моем понимании несколько другой, чем шаблонный класс от которого наследуются реализуемые шаблоны)
Katsiaryna Bazulka35 уровень
23 мая 2017, 19:53
Задача на написание кода не работает. В окне "Код, который надо повторить:" ничего нет, а в "Ваш код:" ничего нельзя ввести.
Vikentsi22 уровень, Минск
20 июля 2017, 18:46
все работает
Евгений40 уровень, Санкт-Петербург
25 октября 2017, 16:01
у меня такая же проблема, но только в браузере IE. в других все в порядке
Сергей Буглак19 уровень
23 апреля 2017, 07:38
Интересно, аж тапки горят )