Абстракція в Java: Абстрактні Класи та Інтерфейси
В Java, абстрактні класи та інтерфейси слугують для реалізації абстракції. В об’єктно-орієнтованому програмуванні абстракція означає приховування деталей реалізації від кінцевих користувачів, дозволяючи їм взаємодіяти з об’єктами на вищому рівні.
У процесі абстракції користувач знає, *що* робить функціонал, але не *як* він реалізований. Розглянемо кожен з цих механізмів детальніше.
Абстрактний Клас
Абстрактний клас в Java – це клас, який неможливо інстанціювати, тобто створити його об’єкт. Він може містити як абстрактні, так і неабстрактні методи. Абстрактний метод – це метод без тіла, тобто без реалізації в момент його оголошення.
Розглянемо приклад абстрактного класу `GraphicObject`.
Для оголошення класу абстрактним, потрібно використати ключове слово `abstract` перед ключовим словом `class`.
abstract class AbstractClass { void run() { System.out.println("виконано"); } }
Абстрактний клас може виступати базовим класом для інших класів, тобто бути розширеним (успадкованим). Він може містити конкретні реалізації методів, а також абстрактні методи, які повинні бути реалізовані у похідних класах.
abstract class AbstractClass { void run() { System.out.println("виконано"); } } class ExtendingAbstractClass extends AbstractClass { void newMethod() { System.out.println("новий метод"); } @Override void run() { System.out.println("перевизначено"); } }
Абстрактні класи корисні для реалізації спільних методів у групі класів, що їх розширюють. Абстрактні методи дозволяють визначити інтерфейс, який повинен бути реалізований різними способами у похідних класах. Розглянемо приклад автомобіля.
Уявімо автомобіль, що має спільні функції, такі як старт, зупинка, рух заднім ходом. Ці функції однакові для всіх типів автомобілів.
Але функції, такі як автономне керування, можуть відрізнятися в залежності від типу автомобіля. Розглянемо, як це можна реалізувати в об’єктно-орієнтованому програмуванні.
Створимо абстрактний клас `Car`, який буде базовим для різних типів автомобілів.
abstract class Car { void start() { System.out.println("запуск двигуна"); } void stop() { System.out.println("двигун зупинено"); } void reverse() { System.out.println("ввімкнено задній хід"); } abstract void selfDrive(); }
Методи `start()`, `stop()` та `reverse()` мають спільну реалізацію для всіх автомобілів. Метод `selfDrive()` оголошений як абстрактний, тому його реалізація буде відрізнятися для кожного типу автомобіля.
class CarTypeA extends Car { @Override void start() { super.start(); } @Override void stop() { super.stop(); } @Override void reverse() { super.reverse(); } void selfDrive() { System.out.println("Автономне керування типу A"); } }
class CarTypeB extends Car { void selfDrive() { System.out.println("Автономне керування типу B"); } }
Якщо підклас не реалізує всі абстрактні методи, визначені в абстрактному класі, він також повинен бути оголошений як абстрактний.
Інтерфейс
Інтерфейс – це спосіб визначення *що* повинен робити клас, але не *як*. Інтерфейс визначає набір методів, які повинні бути реалізовані класом, що його імплементує.
Якщо розглянути приклад автомобіля, інтерфейс може визначати основні функції, такі як запуск, рух та зупинка. Клас, що імплементує інтерфейс, повинен надати реалізацію для всіх цих функцій.
Інтерфейс, як і абстрактний клас, не можна інстанціювати. Інтерфейс можна розглядати як повністю абстрактний клас, що містить тільки абстрактні методи.
Інтерфейс оголошується за допомогою ключового слова `interface`.
interface CAR { void start(); void stop(); void move(); }
Клас імплементує інтерфейс за допомогою ключового слова `implements`.
class CarTypeB implements CAR { public void start() { System.out.println("запущено"); } public void stop() { System.out.println("зупинено"); } public void move() { System.out.println("рухається"); } }
Спільне
Єдиною спільною рисою абстрактних класів та інтерфейсів є неможливість створення їхніх об’єктів.
Відмінності
Характеристика | Абстрактний клас | Інтерфейс |
Успадкування/Імплементація | Клас може успадкувати тільки один абстрактний клас. | Клас може імплементувати декілька інтерфейсів. |
Типи змінних | Може мати кінцеві, некінцеві, статичні та нестатичні змінні. | Може мати тільки статичні та кінцеві змінні. |
Типи методів | Може містити як абстрактні, так і неабстрактні методи. | Може містити тільки абстрактні методи (виняток: статичні методи). |
Модифікатори доступу | Абстрактний клас може мати модифікатори доступу. | Сигнатури методів в інтерфейсі за замовчуванням public. Інтерфейс не має модифікатора доступу. |
Конструктори/Деструктори | Може оголошувати конструктори та деструктори. | Не може оголошувати конструктори чи деструктори. |
Коли використовувати абстрактний клас та інтерфейс?
Використовуйте абстрактні класи, коли:
- Потрібно поділити спільні методи та поля між декількома класами.
- Необхідно оголосити нестатичні та нефінальні поля для зміни стану об’єкта.
Використовуйте інтерфейси, коли:
- Потрібно визначити поведінку класу, але не важлива її конкретна реалізація.
- Необхідно забезпечити реалізацію всіх методів для належного функціонування класу.
Підсумки
Інтерфейси використовуються для створення API, визначаючи структуру для реалізації функціональності. Абстрактні класи використовуються для спільного використання загальних методів між декількома класами, сприяючи повторному використанню коду.
Бажаєте дізнатись більше про Java? Скористайтесь нашими онлайн-курсами. Готуєтесь до співбесіди з Java? Ознайомтесь з типовими питаннями щодо об’єктно-орієнтованого програмування.