1. Treści programowe:
Programowanie
obiektowe, interfejsy deklaracja i
wykorzystanie
2. Cel zajęć:
Zrozumienie zasad
tworzenia i wykorzystania interfejsów. Zrozumienie istniejącej różnicy pomiędzy
interfejsem a klasą abstrakcyjną.
3. Materiały
dydaktyczne:
Interfejs w Javie to kontrakt,
czyli zbiór metod abstrakcyjnych, które definiują zachowanie, jakie klasa musi
zaimplementować. Sam interfejs nie zawiera implementacji metod, a jedynie ich
sygnatury. Można to sobie wyobrazić jako schemat, który mówi: "każdy, kto
używa tego interfejsu, musi mieć te konkretne metody".
Klasa używa
interfejsu za pomocą słowa kluczowego implements.
Klasa, która implementuje interfejs, jest zobowiązana do dostarczenia
implementacji dla wszystkich metod zadeklarowanych w tym interfejsie. Jedna
klasa może implementować wiele interfejsów, co pozwala na osiągnięcie efektu wielodziedziczenia zachowań.
·
W Javie, interfejs może
mieć następujące składowe:
1.
Metody abstrakcyjne
Są
to metody bez ciała (implementacji). Klasa, która implementuje interfejs, musi
dostarczyć implementację dla każdej z tych metod. Są one domyślnie publiczne i abstrakcyjne.
![]()
2.
Metody domyślne (default)
Zostały
wprowadzone w Javie 8. Mają one ciało (implementację) i pozwalają na dodawanie
nowych metod do interfejsu bez łamania kodu w klasach, które go już
implementują. Mogą (ale nie muszą) być nadpisywane przez klasy implementujące.

3.
Metody statyczne
Również
wprowadzone w Javie 8. Mają ciało, ale są związane z samym interfejsem, a nie z
jego obiektami. Można je wywoływać bezpośrednio na interfejsie i nie mogą być
nadpisywane.

4.
Stałe (final fields)
Zmienne
w interfejsach są domyślnie publiczne, statyczne i finalne. Muszą
być zainicjalizowane w momencie deklaracji i nie można zmienić ich wartości.
![]()
5.
Metody prywatne
Dodane
w Javie 9. Służą do hermetyzowania wspólnej logiki wewnątrz interfejsu, którą
można współdzielić między metodami default i
statycznymi.

·
Wykorzystanie interfejsu przez zwykłą implementacje


·
Wykorzystanie interfejsu przez implementacje za pomocą
klas anonimowych
W poniższym programie
zamiast oddzielnych klas Pies i Kot, zaimplementowano interfejs Zwierze za pomocą klas anonimowych. To podejście jest
przydatne, gdy potrzebujesz jednorazowej implementacji interfejsu bez tworzenia
pełnoprawnej klasy.


·
Przykład deklaracji
interfejsu z wszystkimi możliwymi składowymi


·
Podstawowe różnice pomiędzy interfejsem a klasą
abstrakcyjną:
Klasy abstrakcyjne i
interfejsy to dwa kluczowe mechanizmy w Javie do tworzenia abstrakcyjnych typów
danych. Chociaż oba służą do definiowania kontraktu, czyli zbioru metod, które
muszą być zaimplementowane przez klasy dziedziczące, mają kilka istotnych różnic.
Główne różnice
Klasy abstrakcyjne
najlepiej sprawdzają się w hierarchiach, gdzie klasy podrzędne mają wspólne
cechy i zachowania z klasą nadrzędną.
Interfejsy są
natomiast bardziej elastyczne i pozwalają na wielodziedziczenie
zachowań, niezależnie od hierarchii klas.
Od wersji Java 8
interfejsy przestały być "czysto abstrakcyjne". Istnieją trzy rodzaje
metod, które nie są abstrakcyjne:
|
Typ metody |
Czy jest abstrakcyjna? |
Czy musi mieć ciało {}? |
|
Standardowa |
Tak (domyślnie) |
Nie |
|
Default |
Nie |
Tak |
|
Static |
Nie |
Tak |
|
Private |
Nie |
Tak |
Kiedy stosować
klasę abstrakcyjną?
·
Warto
jej użyć, gdy Twoje klasy mają mieć wspólny stan (te same pola, np. protected String name) lub gdy
chcesz wymusić konkretną ścieżkę inicjalizacji obiektu poprzez konstruktor.
Kiedy stosować
interfejs?
·
Gdy
chcesz zdefiniować możliwość lub "umowę" (np. Comparable, Serializable, Runnable). Pozwala to na większą elastyczność, bo klasa
może być np. jednocześnie Pojazdem (extends) i być Naprawialna
oraz Sprzedawalna (implements).
4. Zadania
Zadanie 1.
System płatności
Stwórz interfejs Platnosc z metodą dokonajPlatnosci(double kwota). Następnie utwórz dwie klasy: KartaKredytowa i Blik, które implementują ten interfejs. W
każdej klasie metoda dokonajPlatnosci() powinna
wyświetlić informację o tym, jak płatność została przetworzona (np.
"Płatność BLIKiem na kwotę ... zł została
zrealizowana."). Na koniec, w metodzie main,
utwórz listę płatności i przejdź przez nią, realizując płatność dla każdego z
obiektów.
Zadanie 2.
Odtwarzacz multimediów
Stwórz interfejs Odtwarzacz
z metodami: play(), stop(), pauza(). Utwórz dwie
klasy: OdtwarzaczMp3 i OdtwarzaczWideo, które
implementują ten interfejs. Każda z nich powinna wyświetlić odpowiedni
komunikat dla każdej metody (np. "Odtwarzam plik mp3" lub
"Wstrzymuję odtwarzanie wideo"). Pokaż, jak można użyć polimorfizmu,
przypisując obiekty do zmiennych typu Odtwarzacz i wywołując na nich metody.
Zadanie 3. System rezerwacji biletów
Zaprojektuj interfejs
Rezerwacja z metodami zarezerwujMiejsce(int numerMiejsca) i anulujRezerwacje(int numerMiejsca). Następnie utwórz dwie klasy, które go
implementują: RezerwacjaKinowa i RezerwacjaTeatralna.
Dodaj do interfejsu metodę domyślną sprawdzDostepnosc()
zwracającą true. W klasie RezerwacjaTeatralna
nadpisz tę metodę tak, aby zawsze zwracała false
(symulacja braku miejsc).
Zadanie 4. Kreator raportów
Utwórz interfejs Raportowalny z metodą generujRaport().
Zaimplementuj ten interfejs w trzech różnych klasach, które nie są ze sobą
powiązane, np.: DaneSprzedazy, WynikiAnkiety
i LogiSerwera. Każda klasa powinna mieć swoje własne
pola i w metodzie generujRaport() wyświetlać
podsumowanie tych danych. Pokaż, jak możesz przechowywać obiekty wszystkich
trzech klas w jednej liście typu List<Raportowalny>.
Zadanie 5. Symulator komunikacji
Stwórz interfejs Komunikator
z metodami odbierzWiadomosc() i wyslijWiadomosc(String
wiadomosc). Dodaj do niego metodę statyczną ustawSiec(String siec). Zaimplementuj ten interfejs w
klasach Telefon i Komputer. W metodzie main, utwórz
obiekty obu klas i pokaż, jak można wywołać metody odbierzWiadomosc()
i wyslijWiadomosc() na każdym z nich, a także jak
wywołać metodę statyczną bezpośrednio na interfejsie.
Zadanie 6.
System zarządzania smart-urządzeniami
Opis: Zaprojektuj i zaimplementuj
system do zarządzania urządzeniami w inteligentnym domu, takimi jak żarówki czy
głośniki.
Pamiętaj, że w klasie
SmartZarowka musisz zaimplementować tylko metodę
abstrakcyjną. Pozostałe metody z interfejsu są już gotowe do użycia!