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

Открыта

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

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

— Спасибо!

— Да не за что.

— Помнишь ситуацию, когда мы ввели базовый класс 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 – не имеет смысла. Это не фигура из шахмат, всего лишь абстракция — класс, который мы сделали для удобства. Так работает абстракция из ООП: мы вынесли важные (общие для всех фигур) данные и методы в базовый класс, а их различия оставили в их классах.

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

Для такого случая в 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-методами.

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

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

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

Комментарии (102)
  • популярные
  • новые
  • старые
Для того, чтобы оставить комментарий вы должны авторизоваться
Дмитрий15 уровень, Санкт-Петербург
3 часа назад
Разве в приведенном ниже коде не нужно указывать тип данных для ArrayList в угловых скобках <>? Он же будет Object тогда, и цикл foreach не пройдет..
public void drawAllChessItems()
  {
  //добавляем фигуры в список
  ArrayList items = new ArrayList();
  items.add(new King());
Валихан18 уровень, Санкт-Петербург
9 октября, 10:05
Какая сложная теория и какая легкая практика в сравнении с 1-ым квестом.
Liliia Kyrylenko15 уровень, Cracow
18 октября, 19:48
Пока что все просто. Интересно, как будут обстоять дела дальше
Семён19 уровень, Красногорск
25 сентября, 19:08
Вот три вещи, которые стоит помнить об абстрактных классах. ... 4) Если ты наследовал... Тот момент, когда 3 вещи состоят из 4 пунктов.
Edffom17 уровень, Мирный
15 октября, 02:48
абстрактные классы они такие..
GrooveDevelop24 уровень, Керчь
25 сентября, 08:44
ООП и его принципы - самая понятная и приятная тема из всего программирования.
Алексей17 уровень, Санкт-Петербург
16 сентября, 11:34
— Да сегодня просто день интересных тем!! — Спасибо! Опять диалоги в стиле Тарантино подъехали😕
Имамдин Шарабдинов18 уровень, Владикавказ
14 сентября, 11:22
ладно...пока ничего не понятно. Но надеюсь в дальнейшем столкнуться с этими абстрактными вещами.
sergey16 уровень, Львов
21 августа, 11:21
А можно абстрактный класс унаследовать от другого абстрактного класса?
public abstract  class ChessItem2 extends ChessItem{}
Roman Maltsev34 уровень, Ростов-на-Дону
23 августа, 18:42
Почему бы и нет, это ничему не противоречит , этот вариант подходит под пункт лекции 4 "4) Если ты наследовал свой класс от абстрактного класса, то нужно переопределить все унаследованные абстрактные методы — написать для них реализацию. Иначе такой класс тоже придется объявить абстрактным"
S22 уровень, Минск
26 июля, 15:49
Вопрос - зачем вообще нужны абстрактные классы, если есть интерфейсы? Интерфейсы поддерживают множественное наследование, также могут содержать неабстрактные методы.
Roman Maltsev34 уровень, Ростов-на-Дону
23 августа, 18:49
По функционалу они близки ( хотя и есть различия), Но по прежнему несут разную смысловую нагрузку в абстракции. Абстрактным классом удобно описать модель, а интерфейсом ее поведение. ну и ссылочка
Eiffil24 уровень, Москва
10 сентября, 21:37
ранее в абстрактном классе можно было описывать часть логики (т.е. код в методах). Но вроде в новых версиях java это можно и в интерфейсах делать.
Yuriy41 уровень, Санкт-Петербург
24 сентября, 11:40
Можно сказать что интерфейс это частный случай абстрактного класса: каждый интерфейс это абстрактный класс, но не каждый абстрактный класс является интерфейсом. В интерфейсе все методы абстрактные и нет переменных класса.
S22 уровень, Минск
26 июля, 15:16
Если в классе есть хотя-бы один нереализованный метод,
объявленный прямо в нем или унаследованный от класса-родителя,
 то класс считается абстрактным.
Не знаю - создал себе обычный метод без реализации в обычном классе и компилятор даже не пикнул. По-моему в этом предложении написана лажа.
Александр Малых20 уровень, Коряжма
31 июля, 20:34
убери {} и метод будет нереализованным и компилятор потребует объявления класса абстрактным
Olga Enaldieva19 уровень
19 июня, 09:27
Ого, 14 материи за набор текста!