Abstrakte Klassen und Methoden
Teil des Abschnitts Objektorientierte Programmierung der Java-Journey von Coddy. Lektion 32 von 87.
Manchmal möchten Sie eine Klasse definieren, die als Bauplan dient, aber niemals direkt instanziiert werden sollte. Zum Beispiel ist eine generische Shape-Klasse als Elternklasse sinnvoll, aber wie würde eine „Form“ ohne spezifische Gestalt aussehen? Hier kommen abstrakte Klassen ins Spiel.
Eine abstrakte Klasse wird mit dem Schlüsselwort abstract deklariert und kann nicht instanziiert werden. Sie kann sowohl reguläre Methoden mit Implementierungen als auch abstrakte Methoden ohne Rumpf enthalten:
public abstract class Shape {
protected String color;
public Shape(String color) {
this.color = color;
}
// Abstrakte Methode - keine Implementierung
public abstract double getArea();
// Reguläre Methode - hat eine Implementierung
public String getColor() {
return color;
}
}Abstrakte Methoden deklarieren, was eine Unterklasse tun muss, aber nicht wie. Jede nicht-abstrakte Klasse, die eine abstrakte Klasse erweitert, muss Implementierungen für alle abstrakten Methoden bereitstellen:
public class Circle extends Shape {
private double radius;
public Circle(String color, double radius) {
super(color);
this.radius = radius;
}
@Override
public double getArea() {
return Math.PI * radius * radius;
}
}Sie können abstrakte Klassen weiterhin als Referenztypen verwenden, was Polymorphismus ermöglicht:
Shape shape = new Circle("red", 5.0);
System.out.println(shape.getArea()); // Ruft die Implementierung von Circle aufAbstrakte Klassen sind ideal, wenn Unterklassen gemeinsamen Code teilen, aber jeweils bestimmte Verhaltensweisen unterschiedlich implementieren müssen. Sie erzwingen einen Vertrag und ermöglichen gleichzeitig die Wiederverwendung von Code.
Aufgabe
EinfachErstellen wir ein Gerätesystem, das die Leistungsfähigkeit abstrakter Klassen demonstriert. Du erstellst eine Basisklasse Appliance, die festlegt, was jedes Gerät tun muss, während die spezifischen Gerätetypen selbst entscheiden, wie genau sie dies tun.
Du wirst deinen Code auf vier Dateien verteilen:
Appliance.java: Erstelle eine abstrakte Klasse, die als Vorlage für alle Geräte dient. Jedes Gerät besitzt ein Feldbrand(String) und ein Feldwattage(int). Füge einen Konstruktor hinzu, der beide Felder initialisiert, sowie Getter-Methoden für jedes Feld und eine reguläre MethodegetInfo(), die Folgendes zurückgibt:[brand] - [wattage]W. Definiere eine abstrakte Methodeoperate(), die Unterklassen implementieren müssen – sie stellt dar, wie jedes Gerät seine Hauptfunktion ausführt.WashingMachine.java: Erstelle eine konkrete Klasse, die Appliance erweitert. Waschmaschinen besitzen ein zusätzliches Feldcapacity(int), das die Füllmenge in kg angibt. Verwendesuper, um die Initialisierung der übergeordneten Klasse zu übernehmen. Implementiere die Methodeoperate()so, dass sie Folgendes ausgibt:[brand] washing machine is washing [capacity]kg of clothesMicrowave.java: Erstelle eine weitere konkrete Klasse, die Appliance erweitert. Mikrowellen besitzen ein Feldpower(int), das den Leistungsprozentsatz darstellt. Implementiereoperate()so, dass sie Folgendes ausgibt:[brand] microwave is heating at [power]% powerMain.java: Führe alles mithilfe von Polymorphie zusammen. Du erhältst fünf Eingaben: einen Markennamen, die Wattzahl, die Kapazität der Waschmaschine, einen weiteren Markennamen und die Leistungsstufe der Mikrowelle. Erstelle eine WashingMachine und eine Microwave und speichere sie anschließend in einem Array ausAppliance-Referenzen. Durchlaufe das Array und gib für jedes Gerät seine Informationen mithilfe vongetInfo()aus, gefolgt vom Aufruf vonoperate().
Du erhältst fünf Eingaben in dieser Reihenfolge: erste Marke (String), erste Wattzahl (int), Kapazität in kg (int), zweite Marke (String) und Leistungsstufe (int).
Deine Ausgabe sollte vier Zeilen enthalten – für jedes Gerät siehst du eine Informationszeile, gefolgt von seinem Betriebsverhalten. Beachte, wie die abstrakte Klasse es dir ermöglicht, verschiedene Geräte einheitlich zu behandeln, während jedes Gerät auf seine eigene Weise arbeitet!
Probier es selbst
import java.util.Scanner;
class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
// Eingaben lesen
String brand1 = scanner.nextLine();
int wattage1 = scanner.nextInt();
int capacity = scanner.nextInt();
scanner.nextLine(); // Zeilenumbruch konsumieren
String brand2 = scanner.nextLine();
int power = scanner.nextInt();
// TODO: Erstelle ein WashingMachine Objekt mit brand1, wattage1 und capacity
// TODO: Erstelle ein Microwave Objekt mit brand2, wattage1 (oder entsprechender Wattzahl) und power
// TODO: Erstelle ein Array von Appliance Referenzen und speichere beide Objekte
// TODO: Iteriere durch das Array und für jedes Gerät:
// - Gib seine Informationen mit getInfo() aus
// - Rufe operate() auf
}
}
Diese Lektion enthält ein kurzes Quiz. Starte die Lektion, um es zu beantworten und deinen Fortschritt zu speichern.
Alle Lektionen in Objektorientierte Programmierung
1Grundlagen der OOP
Externe DateienEinführung in die OOPKlassen vs. ObjekteDas Schlüsselwort thisMethodenFelder (Attribute)KonstruktormethodeÜberladen von KonstruktorenRückblick – Einfacher Taschenrechner4Vererbung
Grundlegende Vererbung (extends)Das Schlüsselwort superÜberschreiben von Methoden (@Override)KonstruktorverkettungDie Object-KlasseEinfach- und mehrstufige VererbungWarum keine Mehrfachvererbung von KlassenRückblick – Mitarbeiterhierarchie7Spezielle Methoden & Object-Klasse
toString()-Methodeequals() und hashCode()clone()-MethodecompareTo() und ComparableComparator-SchnittstelleRückblick – Benutzerdefinierte Sortierung2Zugriffsmodifikatoren & Kapselung
Übersicht der ZugriffsebenenGetter- und Setter-MethodenInformationsverbergungDas Schlüsselwort finalRückblick – Bankkontoverwaltung5Polymorphismus
Grundlagen der MethodenüberladungMethodenüberschreibung (Laufzeit)Upcasting und DowncastingDer instanceof-OperatorAbstrakte Klassen und MethodenRückblick – Formrechner8Fortgeschrittene OOP-Konzepte
Komposition vs. VererbungAggregation vs. KompositionInnere, verschachtelte & anonyme KlassenEnums und Enum-MethodenRecords (Java 16+)Versiegelte Klassen (Java 17+)11Entwurfsmuster Teil 1
Einführung in EntwurfsmusterSingleton-MusterFactory-MusterBuilder-MusterObserver-MusterStrategie-Muster14Abschließende Herausforderungen
E-Learning-PlattformBankingsystemEntwicklung einer SpielfigurFahrzeugvermietungsdienst3Klassen-Props & statische Member
Instanz- vs. statische VariablenStatische MethodenStatische BlöckeKonstanten (static final)Wiederholung – Counter & Utility6Schnittstellen & abstrakte Klassen
Einführung in InterfacesInterfaces implementierenMehrere Interfaces implementierenDefault & Static in InterfacesAbstrakte Klassen vs. InterfacesFunktionale InterfacesRückblick – ZahlungssystemÜbe selbstständig: Online-Java-Compiler