Lektionen des Moduls (1/2)
Schnittstellen
Während abstrakte Klassen sowohl teilweise implementierten Code als auch Instanzfelder enthalten können, sind Interfaces (Schnittstellen) in Java reine Verhaltensverträge. Ein Interface definiert, was eine Klasse tun können muss, aber nicht, wie sie es tut.
Dies ermöglicht eine vollständige Entkopplung zwischen der Definition der Operationen und ihrer tatsächlichen Implementierung.
Ein Interface definieren (interface)
Man verwendet das Schlüsselwort interface. Alle in einem Interface deklarierten Methoden sind implizit public und abstract (es ist nicht erforderlich, dies anzugeben):
interface Drivable {
void startEngine();
void stopEngine();
}
Ein Interface implementieren (implements)
Eine Klasse implementiert ein Interface unter Verwendung des Schlüsselworts implements und ist verpflichtet, die Implementierung (mit Rumpf) für alle definierten Methoden bereitzustellen:
class Motorcycle implements Drivable {
@Override
public void startEngine() {
System.out.println("Rombo del motore acceso!");
}
@Override
public void stopEngine() {
System.out.println("Motore spento.");
}
}
Vorteile von Interfaces
- Mehrfachvererbung: In Java kann eine Klasse nur eine einzige Vaterklasse erweitern (Einfachvererbung), aber sie kann mehrere Interfaces gleichzeitig implementieren.
Code
class HybridCar implements Drivable, Chargeable { ... } - Entkopplung: Sie können Variablen unter Verwendung des Interface-Typs definieren. Jedes Objekt, das dieses Interface implementiert, kann einer solchen Variablen zugewiesen werden.
Code
Drivable vehicle = new Motorcycle(); vehicle.startEngine();
Konstanten in Interfaces
In Interfaces ist es möglich, Felder zu deklarieren. Diese Felder sind implizit public static final (d.h. Klassenkonstanten), auch wenn diese Modifikatoren nicht angegeben werden. Folglich müssen sie sofort bei der Deklaration initialisiert werden:
interface PhysicsConstants {
double GRAVITY = 9.81; // Implicitamente public static final
}
Standardmethoden (default)
Ab Java 8 ist es möglich, Methoden mit einer Standardimplementierung innerhalb eines Interface unter Verwendung des Schlüsselworts default zu definieren. Diese Methoden verpflichten die Klassen, die das Interface implementieren, nicht dazu, sie zu überschreiben, was ein Rückfallverhalten bietet:
interface Logger {
void log(String message);
// Metodo di default con corpo
default void logError(String message) {
log("ERRORE: " + message);
}
}
Probiere es aus
Erstellen Sie das Interface Flyable mit der Methode void fly(). Implementieren Sie anschließend die Klasse Bird so, dass sie Flyable implementiert und Flying auf dem Bildschirm ausgibt.
Hinweis anzeigen
Schreiben Sie in Flyable `void fly();`. In der Klasse Bird implementieren Sie die Methode und kennzeichnen sie mit `@Override public void fly() { System.out.println('Flying'); }`.
Lösung nach 3 Versuchen verfügbar
Definieren Sie das Interface Drawable mit der Methode void draw(). Implementieren Sie dann die Klasse Rectangle so, dass sie Drawable implementiert und Drawing Rectangle ausgibt.
Hinweis anzeigen
Definieren Sie `void draw();` im Interface. Verwenden Sie in Rectangle `@Override public void draw() { System.out.println('Drawing Rectangle'); }`.
Lösung nach 3 Versuchen verfügbar
Vervollständigen Sie das Interface Swimmable, indem Sie die Methode void swim() definieren. Vervollständigen Sie anschließend die Klasse Duck so, dass sie sowohl Flyable als auch Swimmable implementiert, wobei Flying in der Methode fly() und Swimming in der Methode swim() ausgegeben wird.
Hinweis anzeigen
Deklarieren Sie `void swim();` in Swimmable. Deklarieren Sie `class Duck implements Flyable, Swimmable` und implementieren Sie beide Methoden, um die geforderten Zeichenketten auszugeben.
Lösung nach 3 Versuchen verfügbar