Middle
Kiedy należy używać interfejsu, a kiedy klasy abstrakcyjnej?
sobes.tech AI
Odpowiedź od AI
Używamy klasy abstrakcyjnej do tworzenia podstawowej funkcjonalności i ogólnego stanu, które mogą dziedziczyć podklasy. Jest odpowiednia, gdy istnieją wspólne metody z implementacją i metody, które muszą być nadpisane. Klasa abstrakcyjna może mieć pola i konstruktory.
// Klasa abstrakcyjna
abstract class Animal {
String name;
public Animal(String name) {
this.name = name;
}
abstract void makeSound(); // Metoda abstrakcyjna
void eat() { // Metoda z implementacją
System.out.println(name + " je.");
}
}
Używamy interfejsu do zdefiniowania kontraktu opisującego zestaw metod, które muszą być zaimplementowane przez klasy. Jest odpowiedni do osiągnięcia wielokrotnego zachowania (wielokrotne dziedziczenie funkcjonalności). Interfejs nie może mieć stanu (pól instancji, oprócz stałych) ani konstruktorów (do Java 8).
// Interfejs
interface Flyable {
void fly(); // Metoda abstrakcyjna
}
Tabela porównawcza różnic:
| Cecha | Klasa abstrakcyjna | Interfejs |
|---|---|---|
| Typ członków | Pola, metody abstrakcyjne i konkretne, konstruktory | Stałe, metody abstrakcyjne (domyślnie), metody statyczne i default (od Java 8) |
| Implementacja metod | Może mieć metody z implementacją | Tylko metody abstrakcyjne do Java 8, od Java 8 - static i default |
| Stan | Może mieć stan (pola) | Nie może mieć stanu (pól instancji) |
| Dziedziczenie | Dziedziczenie pojedyncze | Wielokrotna implementacja |
| Użycie | "jest" (is-a) - typ bazowy | "ma" (has-a) - kontrakt zachowania |