Klassen & Objekte
Verstehe Klassen und Objekte in Java: Das Herzstück der objektorientierten Programmierung. Mit Feldern, Methoden und praktischen Beispielen.
Klassen & Objekte in Java
Willkommen beim Herztueck von Java: der objektorientierten Programmierung (OOP)! In Java ist alles ein Objekt — und Klassen sind die Baupläne fuer diese Objekte. In diesem Kapitel lernst du, wie du eigene Klassen erstellst und damit arbeitest.
Was sind Klassen und Objekte?
Eine Klasse ist wie ein Bauplan. Ein Objekt ist das fertige Produkt, das nach diesem Bauplan gebaut wurde.
Klasse "Auto" (Bauplan) Objekte (konkrete Autos)
┌─────────────────────┐ ┌────────────────────┐
│ Eigenschaften: │ │ marke = "BMW" │
│ - marke │ ───> │ farbe = "Schwarz" │
│ - farbe │ │ kmStand = 15000 │
│ - kmStand │ └────────────────────┘
│ Verhalten: │ ┌────────────────────┐
│ - fahren() │ ───> │ marke = "VW" │
│ - tanken() │ │ farbe = "Rot" │
└─────────────────────┘ │ kmStand = 50000 │
└────────────────────┘
Deine erste Klasse
public class Hund {
// Felder (Eigenschaften)
String name;
String rasse;
int alter;
// Methoden (Verhalten)
void bellen() {
System.out.println(name + " sagt: Wuff!");
}
void vorstellen() {
System.out.printf("%s ist ein %s und %d Jahre alt.%n", name, rasse, alter);
}
}
Objekte erstellen und verwenden
public class HundDemo {
public static void main(String[] args) {
// Objekt erstellen mit "new"
var rex = new Hund();
rex.name = "Rex";
rex.rasse = "Schaeferhund";
rex.alter = 5;
var bella = new Hund();
bella.name = "Bella";
bella.rasse = "Golden Retriever";
bella.alter = 3;
// Methoden aufrufen
rex.bellen(); // Rex sagt: Wuff!
bella.vorstellen(); // Bella ist ein Golden Retriever und 3 Jahre alt.
}
}
Was passiert bei new?
- Java reserviert Speicher fuer das Objekt
- Alle Felder bekommen Default-Werte (null, 0, false)
- Der Konstruktor wird aufgerufen (dazu spaeter mehr)
- Eine Referenz auf das Objekt wird zurueckgegeben
Felder (Instanzvariablen)
Felder speichern den Zustand eines Objekts:
public class Student {
// Felder
String name;
int matrikelnummer;
double notendurchschnitt;
boolean istAktiv;
// Default-Werte:
// name = null
// matrikelnummer = 0
// notendurchschnitt = 0.0
// istAktiv = false
}
Felder vs. lokale Variablen
| Eigenschaft | Felder | Lokale Variablen |
|---|---|---|
| Deklariert in | Klasse | Methode/Block |
| Default-Wert | Ja (null, 0, false) | Nein (muss initialisiert werden) |
| Sichtbarkeit | Ganze Klasse | Nur im Block |
| Lebensdauer | So lange das Objekt lebt | Bis Block endet |
Methoden in Klassen
Methoden definieren das Verhalten eines Objekts:
public class Bankkonto {
String inhaber;
double kontostand;
void einzahlen(double betrag) {
if (betrag > 0) {
kontostand += betrag;
System.out.printf("%.2f EUR eingezahlt. Neuer Stand: %.2f EUR%n", betrag, kontostand);
}
}
void abheben(double betrag) {
if (betrag > 0 && betrag <= kontostand) {
kontostand -= betrag;
System.out.printf("%.2f EUR abgehoben. Neuer Stand: %.2f EUR%n", betrag, kontostand);
} else {
System.out.println("Nicht genug Guthaben!");
}
}
void kontoInfo() {
System.out.printf("Konto von %s: %.2f EUR%n", inhaber, kontostand);
}
}
public class BankDemo {
public static void main(String[] args) {
var konto = new Bankkonto();
konto.inhaber = "Max Mustermann";
konto.kontostand = 1000.0;
konto.kontoInfo(); // Konto von Max Mustermann: 1000.00 EUR
konto.einzahlen(500); // 500.00 EUR eingezahlt. Neuer Stand: 1500.00 EUR
konto.abheben(200); // 200.00 EUR abgehoben. Neuer Stand: 1300.00 EUR
konto.abheben(5000); // Nicht genug Guthaben!
}
}
Das this-Schluesselwort
this verweist auf das aktuelle Objekt. Es ist besonders nuetzlich, wenn Parameter und Felder den gleichen Namen haben:
public class Person {
String name;
int alter;
void setName(String name) {
this.name = name; // this.name = Feld, name = Parameter
}
void setAlter(int alter) {
this.alter = alter;
}
void vorstellen() {
System.out.println("Ich bin " + this.name + ", " + this.alter + " Jahre alt.");
}
}
Records — Kompakte Datenklassen (Java 16+)
Fuer Klassen, die hauptsaechlich Daten speichern, gibt es seit Java 16 Records:
// Statt dieser ganzen Klasse:
public class PersonAlt {
private final String name;
private final int alter;
public PersonAlt(String name, int alter) {
this.name = name;
this.alter = alter;
}
public String getName() { return name; }
public int getAlter() { return alter; }
@Override
public String toString() {
return "Person[name=" + name + ", alter=" + alter + "]";
}
@Override
public boolean equals(Object o) { /* ... */ return false; }
@Override
public int hashCode() { /* ... */ return 0; }
}
// Schreibe einfach:
record Person(String name, int alter) {}
Records generieren automatisch:
- Einen Konstruktor mit allen Feldern
- Getter (ohne
get-Prefix):person.name(),person.alter() - toString(), equals() und hashCode()
var max = new Person("Max", 25);
System.out.println(max.name()); // Max
System.out.println(max.alter()); // 25
System.out.println(max); // Person[name=Max, alter=25]
var max2 = new Person("Max", 25);
System.out.println(max.equals(max2)); // true
Records mit eigenen Methoden
record Rechteck(double breite, double hoehe) {
double flaeche() {
return breite * hoehe;
}
double umfang() {
return 2 * (breite + hoehe);
}
boolean istQuadrat() {
return breite == hoehe;
}
}
var r = new Rechteck(5, 3);
System.out.println("Flaeche: " + r.flaeche()); // 15.0
System.out.println("Umfang: " + r.umfang()); // 16.0
System.out.println("Quadrat: " + r.istQuadrat()); // false
Vergleich mit Python
# Python: Klasse
class Hund:
def __init__(self, name, rasse):
self.name = name
self.rasse = rasse
def bellen(self):
print(f"{self.name} sagt: Wuff!")
rex = Hund("Rex", "Schaeferhund")
rex.bellen()
// Java: Klasse
public class Hund {
String name;
String rasse;
Hund(String name, String rasse) {
this.name = name;
this.rasse = rasse;
}
void bellen() {
System.out.println(name + " sagt: Wuff!");
}
}
var rex = new Hund("Rex", "Schaeferhund");
rex.bellen();
| Python | Java |
|---|---|
self | this |
__init__ | Konstruktor (Klassenname) |
| Keine Typen | Typen erforderlich |
class Hund: | public class Hund { } |
Mehrere Klassen zusammen verwenden
record Adresse(String strasse, String stadt, String plz) {}
public class Mitarbeiter {
String name;
String position;
double gehalt;
Adresse adresse; // Ein Objekt als Feld!
void info() {
System.out.printf("%s (%s) - %.2f EUR%n", name, position, gehalt);
System.out.printf("Wohnt in: %s, %s %s%n",
adresse.strasse(), adresse.plz(), adresse.stadt());
}
}
var adresse = new Adresse("Hauptstr. 1", "Berlin", "10115");
var mitarbeiter = new Mitarbeiter();
mitarbeiter.name = "Anna Mueller";
mitarbeiter.position = "Entwicklerin";
mitarbeiter.gehalt = 65000;
mitarbeiter.adresse = adresse;
mitarbeiter.info();
null und NullPointerException
Referenztypen koennen null sein — “kein Objekt”:
Hund hund = null;
// Das hier knallt!
// hund.bellen(); // NullPointerException!
// Immer erst pruefen:
if (hund != null) {
hund.bellen();
}
Die NullPointerException ist der haeufigste Fehler in Java. Gewoehne dir an, Referenzen vor der Nutzung zu pruefen.
Uebungen
Uebung 1: Buch-Klasse
Erstelle eine Klasse Buch mit Feldern titel, autor, seiten und preis. Fuege Methoden info() und istLang() (> 300 Seiten) hinzu.
Uebung 2: Kreis-Record
Erstelle einen Record Kreis mit dem Radius. Fuege Methoden fuer flaeche(), umfang() und durchmesser() hinzu.
Uebung 3: Einkaufswagen
Erstelle eine Klasse Einkaufswagen mit einer ArrayList von Produkten (als Record Produkt(String name, double preis)). Fuege Methoden hinzufuegen(), gesamtpreis() und anzeigen() hinzu.
Uebung 4: Spieler-Verwaltung
Erstelle eine Klasse Spieler mit Name, Level und Erfahrungspunkten. Fuege eine Methode erfahrungSammeln(int punkte) hinzu, die bei genug Punkten automatisch das Level erhoeht.
Was kommt als Naechstes?
In der naechsten Lektion vertiefen wir das Thema mit Konstruktoren — der elegante Weg, Objekte mit Startwerten zu erstellen.
Zusammenfassung
- Eine Klasse ist ein Bauplan, ein Objekt ist eine Instanz davon
- Felder speichern den Zustand, Methoden definieren das Verhalten
- Objekte werden mit
newerstellt thisverweist auf das aktuelle Objekt- Records sind kompakte, unveraenderliche Datenklassen (Java 16+)
nullbedeutet “kein Objekt” — Vorsicht vorNullPointerException!- Klassen koennen andere Objekte als Felder enthalten (Komposition)
Pro-Tipp: Nutze Records, wann immer du einfache Datencontainer brauchst. Sie sparen dir dutzende Zeilen Boilerplate-Code! In IntelliJ kannst du eine normale Klasse automatisch in einen Record umwandeln: Rechtsklick > Refactor > Convert to Record. Und denke daran: Ein gutes Java-Programm besteht aus vielen kleinen Klassen, nicht aus einer riesigen.