— Привіт, Аміго! Зараз буде нова цікава тема.

— Та сьогодні просто день цікавих тем!

— Дякую!

— Та нема за що.

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

— Так.

—Тепер уяви, що кожна фігура має метод, який займається її малюванням на екрані. Викликаєш метод, і фігура сама себе малює у поточних координатах. Чи зручно було б винести цей метод до базового класу?

— Так. Після того, що я дізнався про поліморфізм, можна було б викликати метод малювання для всіх фігур незалежно від їхнього типу. Приблизно так:

Приклад
class ChessBoard
{
  public void drawAllChessItems()
  {
  //додаємо фігури до списку
  ArrayList<ChessItem> 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(); //абстрактний метод. Реалізація відсутня.

}

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

Якщо в класі є хоч один абстрактний метод, клас також позначається ключовим словом abstract.

3) Створювати об'єкти абстрактного класу не можна. Такий код просто не скомпілюється.

Код на Java Опис
ChessItem item = new ChessItem();
item.draw();
Цей код не скомпілюється
ChessItem item = new Queen();
item.draw();
А так можна

4) Якщо ти успадкував свій клас від абстрактного класу, потрібно перевизначити всі успадковані абстрактні методи — написати для них реалізацію. В іншому разі такий клас також доведеться оголосити абстрактним. Якщо в класі є хоча б один нереалізований метод, оголошений прямо в ньому або успадкований від класу-батька, клас вважається абстрактним.

— А навіщо це все потрібно? Для чого потрібні абстрактні класи? Хіба не можна замість них використати звичайні? А замість абстрактних методів просто писати дві дужки як тіло методу — {} ?

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

Те саме і з абстрактним класом. Той, хто написав цей клас, не хоче, щоби створювалися його об'єкти.Навпаки, він розраховує на те, щоб від його абстрактного класу успадковувалися та перевизначали абстрактні методи.

— Все одно не зрозуміло, навіщо ускладнювати собі життя?

— Перевага цього відчутна на великих проєктах. Чим більше класів, тим чіткіше доводиться окреслювати їхні ролі. Ти зрозумієш перевагу цього, і вже найближчим часом. Усі через це проходять.