Java OOP-Konzepte
Überblick über OOP in Java: Kapselung, Vererbung, Polymorphismus und Abstraktion mit Beispielen.
Objektorientierte Programmierung (OOP) ist eine Methode, Code um die Dinge in deinem Programm zu organisieren, anstatt um die Schritte. Statt eines langen Skripts, das rohe Variablen verarbeitet, beschreibst du die Arten von Objekten in deiner Domäne — ein User, eine Order, ein BankAccount — und gibst jedem die Daten und das Verhalten, das es benötigt. Der Rest des Programms fordert diese Objekte dann auf, Dinge zu tun, anstatt direkt in ihre Interna einzugreifen.
Java wurde um diese Idee herum aufgebaut. Jede Zeile Java-Code, die du schreibst, lebt innerhalb einer Klasse, und eine Klasse ist der Bauplan, aus dem Objekte erzeugt werden. Bis zu diesem Punkt hast du meist prozeduralen Code innerhalb von main und ein paar statischen Hilfsmethoden geschrieben; ab diesem Teil des Buches beginnst du, eigene Klassen zu entwerfen.
Klassen und Objekte in einem Satz
Eine Klasse beschreibt eine Art von Ding — welche Daten es enthält und was es tun kann. Ein Objekt ist eine konkrete Instanz dieses Dings.
public class Dog {
String name;
int age;
void bark() {
System.out.println(name + " says woof");
}
}
Dog d = new Dog(); // d is an object — one specific dog
d.name = "Rex";
d.bark(); // Rex says woofDog ist die Klasse. d ist ein Objekt. Der entscheidende Unterschied zum prozeduralen Code: Ein Objekt bündelt Zustand (die name- und age-Felder) und Verhalten (die bark()-Methode) in einer Einheit. Du kannst beliebig viele Dog-Objekte erstellen; jedes bekommt seine eigene Kopie von name und age, und jedes kann eigenständig bark(). Das Kapitel Klassen & Objekte erklärt dies im Detail.
Die vier Säulen
OOP wird üblicherweise anhand von vier Ideen gelehrt. Jede davon bekommt später in diesem Teil des Buches ein eigenes Kapitel — was folgt, ist ein dreißigsekundiger Überblick, damit du weißt, wohin der Weg führt.
Kapselung
Halte die Daten eines Objekts privat; stelle stattdessen Verhalten bereit. Außenstehender Code ruft account.deposit(50) auf, nicht account.balance += 50. Der Vorteil: Die Klasse kontrolliert ihre eigenen Invarianten — niemand sonst kann sie in einen ungültigen Zustand versetzen.
public class Account {
private int balance; // hidden
public void deposit(int amount) { // public behavior
if (amount <= 0) throw new IllegalArgumentException();
balance += amount;
}
}Siehe das Kapitel Kapselung.
Vererbung
Eine Klasse kann eine andere erweitern, ihre Felder und Methoden übernehmen und ergänzen. Cat extends Animal verwendet alles wieder, was Animal bereits tut, und legt nur fest, was bei Katzen anders ist.
public class Animal {
void breathe() { System.out.println("inhale, exhale"); }
}
public class Cat extends Animal {
void purr() { System.out.println("rrr"); }
}
Cat c = new Cat();
c.breathe(); // inherited
c.purr(); // ownSiehe das Kapitel Vererbung.
Polymorphismus
Derselbe Aufruf kann je nach dem tatsächlichen Objekt am anderen Ende unterschiedliche Dinge tun. Eine Variable vom Typ Animal kann auf eine Cat, einen Dog oder eine Cow zeigen — der Aufruf von speak() wählt das richtige Verhalten zur Laufzeit.
Animal a = new Cat();
a.speak(); // calls Cat's speak, even though a is typed as AnimalSiehe das Kapitel Polymorphismus.
Abstraktion
Definiere was etwas tut, ohne festzulegen, wie. Ein interface Shape besagt, dass jede Form eine area()-Methode hat; jede konkrete Form — Circle, Square — liefert ihre eigene Formel. Code, der mit Formen arbeitet, muss nicht wissen, um welche Art es sich handelt.
public interface Shape {
double area();
}Siehe das Kapitel Abstraktion.
Die Säulen auf einen Blick
| Säule | Grundidee | Java-Werkzeug |
|---|---|---|
| Kapselung | Daten verstecken, Verhalten bereitstellen | private-Felder + öffentliche Methoden |
| Vererbung | Eine andere Klasse wiederverwenden und erweitern | extends |
| Polymorphismus | Ein Aufruf, Verhalten zur Laufzeit gewählt | Überschreiben + Supertyp-Variablen |
| Abstraktion | Was definieren, nicht wie | Interfaces und abstrakte Klassen |
Die Säulen überschneiden sich absichtlich: Polymorphismus stützt sich auf Vererbung, Abstraktion wird durch Kapselung durchgesetzt und so weiter. Betrachte sie als vier Blickwinkel auf eine Idee — modelliere dein Programm als zusammenarbeitende Objekte — und nicht als vier separate Features, die es auswendig zu lernen gilt.
Warum der Aufwand?
Für ein 20-zeiliges Skript ist OOP überdimensioniert. Die Vorteile zeigen sich, wenn Programme wachsen:
- Lokales Denken. Eine
BankAccount-Klasse besitzt ihre eigenen Regeln. Um Einzahlungen zu verstehen oder zu ändern, liest du diedeposit-Methode — du musst nicht die gesamte Codebase nachbalance +=durchsuchen. - Wiederverwendung ohne Kopieren. Vererbung und Komposition ermöglichen es
SavingsAccount, aufAccountaufzubauen, anstatt es zu duplizieren. - Austauschbarkeit. Eine Funktion, die eine
Shapeentgegennimmt, funktioniert für jede heute vorhandene Form und jede, die du morgen hinzufügst. - Testbarkeit. Kleine Objekte mit klaren Verantwortlichkeiten sind leicht zu instanziieren, anzusteuern und zu testen.
Java ist bei Weitem nicht die einzige objektorientierte Sprache — Python, C#, Kotlin, Ruby und viele andere teilen dieselben Ideen mit unterschiedlicher Syntax. Was du in diesem Teil lernst, lässt sich übertragen.
OOP ist nicht das einzige Paradigma
Auch innerhalb von Java hast du bereits Code geschrieben, der nicht strikt OO ist: statische Hilfsmethoden, einfache Mathematik, gewöhnliche Kontrollstrukturen. Modernes Java mischt Paradigmen — funktionale Pipelines mit Streams und Lambdas, unveränderliche Daten mit Records, deklarative Arbeit mit Annotationen. OOP ist das Rückgrat der Sprache, kein Käfig. Verwende eine Klasse, wenn du etwas mit Zustand und Verhalten modellierst; greife auf eine statische Methode zurück, wenn du nur eine Berechnung benötigst.
Ein durchgearbeitetes Beispiel
Der vollständige Code aus den obigen Ausschnitten, zusammengefasst, damit du ihn ausführen kannst:
Was kommt als Nächstes
Jetzt, wo du die Struktur von OOP kennst, legt das nächste Kapitel die Grundlagen fest: wie aus einer Klassendefinition ein Objekt im Speicher wird, was new tatsächlich tut und wie sich Objektreferenzen von primitiven Typen unterscheiden. Weiter zu Java-Klassen und Objekte.