Розділ 15: Абстракція, абстрактний клас і інтерфейс: тріо ООП, частина 1

pic

Зображення: freepik

Перед тим, як перейти до більш складних прикладів абстракції (abstract class та Interface), давайте спершу розглянемо базову версію, наступні 2 частини цієї короткої серії будуть складнішими, оскільки ми знову перейдемо до платіжних систем.

Що таке абстракція?

Розглядайте абстракцію як мистецтво приховування непотрібних деталей, показуючи лише найважливіше. Це як водіння автомобіля: вам не потрібно знати, як працює двигун, але ви знаєте, що натискання на акселератор змушує його ричати.

В програмуванні абстракція дозволяє зосередитися на чому робить об'єкт, а не як він це робить.

Може виникнути деяка плутанина з інкапсуляцією, оскільки спочатку мені було складно розрізнити їх, але давайте прояснимо це:

  • Інкапсуляція приховує дані (обмежує прямий доступ).
  • Абстракція приховує реалізацію.

Обидва ці принципи спрямовані на те, щоб показати лише те, що необхідно, але інкапсуляція більше стосується захисту внутрішніх станів, а абстракція – спрощення використання. Чи стало це зрозуміліше? 😊

Ось текстове уявлення для візуалізації взаємозв'язку між класами, підкласами, абстрактними класами та їх підкласами:

Звичайний клас та підкласи

Class: Animal  
+---------------------+  
| Animal |  
|---------------------|  
| - name: String | <-- Атрибути (приватні змінні)  
| - age: int |  
|---------------------|  
| + eat(): void | <-- Методи (публічні поведінки)  
| + speak(): void |  
+---------------------+  
| (Наслідування)  
 v  
Subclass: Dog  
+---------------------+  
| Dog |  
|---------------------|  
| + speak(): void | <-- Реалізація методу speak  
+---------------------+  
 | (Наслідування)  
 v  
Subclass: Cat  
+---------------------+  
| Cat |  
|---------------------|  
| + speak(): void | <-- Реалізація методу speak  
+---------------------+

Абстрактний клас і підкласи

Abstract Class: Animal  
+---------------------+  
| Animal |  
|---------------------|  
| + speak(): void | <-- Абстрактний метод (без реалізації)  
|---------------------|  
| + eat(): void | <-- Конкретний метод (спільна реалізація)  
+---------------------+  

| (Наслідування)  
 v  
Subclass: Dog  
+---------------------+  
| Dog |  
|---------------------|  
| + speak(): void | <-- Реалізація абстрактного методу  
+---------------------+  
 | (Наслідування)  
 v  
Subclass: Cat  
+---------------------+  
| Cat |  
|---------------------|  
| + speak(): void | <-- Реалізація абстрактного методу  
+---------------------+

Ключові примітки:

  • Звичайний клас: Може бути інстанційований безпосередньо (наприклад, Dog dog = new Dog();).
  • Абстрактний клас: Не може бути інстанційований безпосередньо. Його підкласи повинні реалізувати всі абстрактні методи, якщо вони не є абстрактними самі по собі.
  • Підкласи: Наслідують атрибути та методи від свого батьківського класу, але також можуть мати свої власні унікальні атрибути та поведінку.

Приклад коду

Припустимо, ми створюємо систему зоопарку. Ось абстрактний приклад:

abstract class Animal {  
 abstract void speak(); // Без реалізації - це абстрактно!  

 void eat() { // Конкретний метод - всі тварини їдять.  
 System.out.println("Ця тварина їсть їжу.");  
 }  
}

Тут клас Animal надає загальний шаблон для всіх тварин. Він каже: «Підкласи, ви повинні визначити метод speak() , але я оброблю логіку eat() для вас.»

Абстрактні класи: Керований шаблон

Абстрактний клас – це як напівготова будівля. Вона має основну структуру, але залишає місце для налаштувань. Ви можете змішувати абстрактні методи (чисті ідеї) з конкретними методами (реальними реалізаціями).

Приклад

abstract class Animal {  
 abstract void speak(); // Повинен бути реалізований підкласами.  

 void eat() { // Спільна реалізація для всіх тварин.  
 System.out.println("Ця тварина їсть їжу.");  
 }  
}

System.out.println("Ця тварина їсть їжу.");  
 }  
}  

class Dog extends Animal {  
 void speak() {  
 System.out.println("Гав!");  
 }  
}  
class Cat extends Animal {  
 void speak() {  
 System.out.println("Мяу!");  
 }  
}  
public class Main {  
 public static void main(String[] args) {  
 Animal dog = new Dog();  
 dog.speak(); // Вивід: Гав!  
 dog.eat(); // Вивід: Ця тварина їсть їжу.  
 Animal cat = new Cat();  
 cat.speak(); // Вивід: Мяу!  
 }  
}

Тут Dog і Cat реалізують свої версії методу speak(), одночасно використовуючи метод eat() з класу Animal.

Інтерфейс: Абсолютний контракт

Тепер давайте піднімемо рівень. Що, якщо ми хочемо, щоб непов'язані класи дотримувалися одних і тих же правил? Ось тут вступає інтерфейс, інструмент 100% абстракції. Це як контракт: "Якщо ти мене реалізуєш, ти повинен надавати ці методи."

Приклад

interface Animal {  
 void speak(); // Без реалізації тут - просто контракт!  
}  

class Dog implements Animal {  
 public void speak() {  
 System.out.println("Гав!");  
 }  
}  
class Cat implements Animal {  
 public void speak() {  
 System.out.println("Мяу!");  
 }  
}  
public class Main {  
 public static void main(String[] args) {  
 Animal dog = new Dog();  
 dog.speak(); // Вивід: Гав!  
 Animal cat = new Cat();  
 cat.speak(); // Вивід: Мяу!  
 }  
}

Зверніть увагу на відмінності:

  1. Animal тепер є інтерфейсом, а не класом.
  2. Ми змушуємо виконання контракту speak(), але не залишаємо місця для спільної логіки, як eat().

Абстракція vs Абстрактний клас vs Інтерфейс

Ось розбір у чистому, структурованому форматі для легшого розуміння:

1. Визначення

  • Абстракція: Приховування непотрібних деталей і надання лише основних функцій.
  • Абстрактний клас: Напівготовий клас, який може містити як реалізовані (конкретні) методи, так і нереалізовані (абстрактні) методи.
  • Інтерфейс: Повністю абстрактний контракт, який визначає методи, які клас повинен реалізувати.

2. Реалізація

  • Абстракція: Це концепція, не прив'язана до конкретного коду.
  • Абстрактний клас: Може містити змішування абстрактних методів (без реалізації) та конкретних методів (з реалізацією).
  • Інтерфейс: Тільки абстрактні методи, що робить його чистою абстракцією.

3. Поля/Властивості

  • Абстракція: Не застосовується безпосередньо до полів чи властивостей.
  • Абстрактний клас: Може мати змінні екземплярів і константи.
  • Інтерфейс: Тільки константи (за замовчуванням статичні та фінальні).

4. Множинне наслідування

  • Абстракція: Не є прямою особливістю, але принцип може працювати між кількома сутностями.
  • Абстрактний клас: Не підтримується в Java; клас може успадковувати тільки один абстрактний клас.
  • Інтерфейс: Підтримується в Java через множинні інтерфейси.

5. Використання

  • Абстракція: Загальний принцип ООП для спрощення та модульності коду.
  • Абстрактний клас: Використовується для спільного функціоналу серед пов'язаних класів, з деякими методами, що залишаються для визначення підкласами.
  • Інтерфейс: Використовується для забезпечення контракту серед непов'язаних класів або коли потрібне множинне наслідування.

Коли що використовувати?

  • Абстракція: Основна концепція для проектування чистих, модульних систем.
  • Абстрактний клас: Використовуйте його, коли є спільний функціонал для подібних класів. Розглядайте його як основу для групи схожих об'єктів.
  • Інтерфейс: Використовуйте, коли потрібно, щоб абсолютно непов'язані класи поділяли спільний контракт, або коли потрібно множинне наслідування.

Підсумок

  1. Абстракція – це мета: спростити ваш код і зробити його більш модульним.
  2. Абстрактні класи – інструмент для часткової абстракції, який дозволяє ділитися логікою з деякими методами, які залишаються для підкласів, абстрактний клас extends.
    3.
    Інтерфейси є інструментом для чистої абстракції, забезпечуючи суворий "контракт" для кожного класу, який їх реалізує.

ПІДКАЗКА: Коли ви створюєте клас, наприклад, public class baseZoo, замініть public на abstract, і тепер це абстрактний клас, який буде виглядати як abstract class baseZoo, тепер ви можете додавати в нього не реалізовані методи.

Перевірити та завантажити код можна тут

.

.

.

Щасливого кодування!

Перекладено з: Chapter[15]: Abstraction, Abstract Class, and Interface: The OOP Trio Explained: Part 1

Leave a Reply

Your email address will not be published. Required fields are marked *