Implementacja wielu interfejsów
Część sekcji Programowanie obiektowe ścieżki Java w Coddy. Lekcja 36 z 87.
W przeciwieństwie do dziedziczenia klas, w którym można rozszerzyć tylko jedną klasę, Java pozwala klasie implementować wiele interfejsów. W ten sposób Java bezpiecznie realizuje pewną formę wielokrotnego dziedziczenia.
Aby zaimplementować wiele interfejsów, wymień je po słowie kluczowym implements, oddzielając je przecinkami:
public interface Drawable {
void draw();
}
public interface Resizable {
void resize(int width, int height);
}
public class Rectangle implements Drawable, Resizable {
private int width, height;
public Rectangle(int width, int height) {
this.width = width;
this.height = height;
}
@Override
public void draw() {
System.out.println("Drawing rectangle " + width + "x" + height);
}
@Override
public void resize(int width, int height) {
this.width = width;
this.height = height;
}
}Klasa musi implementować wszystkie metody z każdego interfejsu, który deklaruje. Możesz także łączyć dziedziczenie z wieloma interfejsami:
public class Square extends Shape implements Drawable, Resizable {
// Musi implementować metody z obu interfejsów
// Może również używać elementów odziedziczonych po Shape
}Ta elastyczność pozwala projektować klasy pełniące wiele ról. SmartPhone może implementować interfejsy Callable, Messageable i Browsable, z których każdy definiuje inne możliwości obsługiwane przez telefon.
Wyzwanie
ŁatwyZbudujmy system inteligentnych urządzeń, w którym urządzenia mogą mieć wiele możliwości. Utworzysz SmartTV, którym można zarówno włączać i wyłączać zasilanie, jak i sterować głośnością: zademonstrujesz w ten sposób, jak jedna klasa może implementować wiele interfejsów, aby pełnić różne role.
Rozmieścisz swój kod w czterech plikach:
Powerable.java: Zdefiniuj interfejs dla urządzeń, które można włączać i wyłączać. Powinien deklarować dwie metody:powerOn()ipowerOff(), obie zwracające void.VolumeControl.java: Zdefiniuj interfejs dla urządzeń z regulacją głośności. Powinien deklarować metodęsetVolume(int level), która zwraca void, oraz metodęgetVolume(), która zwraca int.SmartTV.java: Utwórz klasę implementującą oba interfejsy:PowerableiVolumeControl. Twój SmartTV powinien mieć polebrand(String), poleisOn(boolean, początkowo false) oraz polevolume(int, początkowo 0). Dodaj konstruktor przyjmujący nazwę marki. Zaimplementuj wszystkie wymagane metody:powerOn()powinno ustawićisOnna true i wypisać:[brand] TV is now ONpowerOff()powinno ustawićisOnna false i wypisać:[brand] TV is now OFFsetVolume(int level)powinno zaktualizować głośność i wypisać:[brand] TV volume set to [level]getVolume()powinno zwrócić bieżącą głośność
Main.java: Połącz wszystko, aby zademonstrować implementację wielu interfejsów. Otrzymasz dwa dane wejściowe: nazwę marki (String) i poziom głośności (int). Utwórz SmartTV z podaną marką, a następnie:- Wywołaj
powerOn() - Wywołaj
setVolume()z podanym poziomem - Wypisz:
Current volume: [volume], używającgetVolume() - Wywołaj
powerOff()
- Wywołaj
Otrzymasz dwa dane wejściowe: markę telewizora (String) i poziom głośności (int).
Twój wynik powinien zawierać cztery wiersze demonstrujące, jak Twój SmartTV spełnia wymagania obu interfejsów. Można go włączać i wyłączać jak każde urządzenie Powerable, a także sterować jego głośnością jak w przypadku każdego urządzenia VolumeControl!
Spróbuj swoich sił
import java.util.Scanner;
class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
// Odczytaj dane wejściowe
String brand = scanner.nextLine();
int volumeLevel = scanner.nextInt();
// TODO: Utwórz SmartTV o podanej marce
// TODO: Wywołaj powerOn()
// TODO: Wywołaj setVolume() z podanym poziomem
// TODO: Wypisz: Current volume: [volume], używając getVolume()
// TODO: Wywołaj powerOff()
}
}
Ta lekcja zawiera krótki quiz. Zacznij lekcję, żeby na niego odpowiedzieć i śledzić swoje postępy.
Wszystkie lekcje w sekcji Programowanie obiektowe
1Podstawy programowania obiektowego
Pliki zewnętrzneWprowadzenie do programowania obiektowegoKlasy a obiektySłowo kluczowe thisMetodyPola (atrybuty)Metoda konstruktoraPrzeciążanie konstruktoraPodsumowanie — prosty kalkulator4Dziedziczenie
Podstawy dziedziczenia (extends)Słowo kluczowe superPrzesłanianie metod (@Override)Łańcuch wywołań konstruktorówKlasa ObjectDziedziczenie jedno- i wielopoziomoweDlaczego Java nie obsługuje wielodziedziczenia klasPodsumowanie – hierarchia pracowników7Metody specjalne i klasa Object
Metoda toString()equals() i hashCode()Metoda clone()compareTo() i ComparableInterfejs ComparatorPodsumowanie — własne sortowanie10Obsługa wyjątków w programowaniu obiektowym
Hierarchia klas wyjątkówWłasne wyjątkiBłędy sprawdzane a niesprawdzaneWzorzec try-with-resourcesPodsumowanie – zweryfikowany użytkownik2Modyfikatory dostępu i enkapsulacja
Przegląd poziomów dostępuMetody pobierające i ustawiająceUkrywanie informacjiSłowo kluczowe finalPodsumowanie — menedżer kont bankowych5Polimorfizm
Podstawy przeciążania metodPrzesłanianie metod (w czasie wykonywania)Rzutowanie w górę i w dółOperator instanceofKlasy i metody abstrakcyjnePowtórka — kalkulator figur8Zaawansowane koncepcje OOP
Kompozycja a dziedziczenieAgregacja a kompozycjaKlasy wewnętrzne, zagnieżdżone i anonimoweEnumy i metody enumówRekordy (Java 16+)Klasy zapieczętowane (Java 17+)11Wzorce projektowe — część 1
Wprowadzenie do wzorców projektowychWzorzec SingletonWzorzec FactoryWzorzec BuilderWzorzec ObserverWzorzec Strategy3Właściwości klas i składowe statyczne
Zmienne instancji a zmienne statyczneMetody statyczneBloki statyczneStałe (static final)Powtórka – Counter i Utility6Interfejsy i klasy abstrakcyjne
Wprowadzenie do interfejsówImplementowanie interfejsówImplementacja wielu interfejsówMetody domyślne i statyczne w interfejsieKlasy abstrakcyjne a interfejsyInterfejsy funkcyjnePodsumowanie — system płatnościPoćwicz samodzielnie: Kompilator Java online