Klassen, Vererbung und UML
Die Stadt Köln plant eine Verkehrssimulation: Autos, Busse und Fahrräder sollen sich über einen Stadtplan bewegen. Jedes Fahrzeug hat eine Position und eine Geschwindigkeit, aber jedes bewegt sich anders. Wie baust du ein Programm, in dem du nicht für jedes Fahrzeug alles neu schreiben musst und trotzdem neue Fahrzeugtypen leicht ergänzen kannst? Genau dafür gibt es die Objektorientierung.
Klassen und Objekte
Eine Klasse ist ein Bauplan. Sie beschreibt, welche Attribute (Eigenschaften) und welche Methoden (Fähigkeiten) Dinge einer Art haben. Ein Objekt ist ein konkretes Exemplar nach diesem Bauplan, mit eigenen Attributwerten (Zustand).
In UML (Unified Modeling Language) zeichnest du eine Klasse als Rechteck mit drei Abschnitten: Name, Attribute, Methoden.
- bedeutet private, + bedeutet public. Der Objektname im Objektdiagramm wird unterstrichen geschrieben; hier steht er der Einfachheit halber im Kopf des Kastens.
In Java erzeugst du ein Objekt mit new. Der Konstruktor setzt die Anfangswerte:
public class Fahrrad {
private String farbe;
private int gaenge;
public Fahrrad(String farbe, int gaenge) {
this.farbe = farbe;
this.gaenge = gaenge;
}
}
// Fahrrad meinRad = new Fahrrad("rot", 21);
Eine Klasse Fahrrad hat die Attribute farbe (String) und gaenge (int) sowie die Methode schalte(int g). a) Zeichnen Sie das UML-Klassendiagramm (als Text mit drei…
Eine Klasse Fahrrad hat die Attribute farbe (String) und gaenge (int) sowie die Methode schalte(int g).
- a) Zeichnen Sie das UML-Klassendiagramm (als Text mit drei Abschnitten).
- b) Erklären Sie den Unterschied zwischen Klasse und Objekt und geben Sie ein Beispielobjekt an.
Kapselung: private und public
Würde jeder von außen direkt an stand eines Kontos schreiben, könnte jemand den Kontostand auf einen unsinnigen Wert setzen. Deshalb gilt das Geheimnisprinzip (Kapselung):
-
private: Zugriff nur innerhalb der eigenen Klasse. -
public: Zugriff von überall.
Attribute sind meist private. Der Zugriff läuft über öffentliche Methoden: Getter (lesen) und Setter oder andere Methoden (ändern), die Bedingungen prüfen.
Gegeben ist die Klasse a) Erklären Sie die Bedeutung von private und public. b) Ergänzen Sie eine Methode einzahlen(double betrag), die nur positive Beträge akzeptiert.
Gegeben ist die Klasse
public class Konto {
private double stand;
public double getStand() { return stand; }
}
- a) Erklären Sie die Bedeutung von
privateundpublic.
- b) Ergänzen Sie eine Methode
einzahlen(double betrag), die nur positive Beträge akzeptiert.
Vererbung und abstrakte Klassen
Hunde und Katzen sind beide Tiere: Sie haben einen Namen und ein Alter. Statt das zweimal zu schreiben, legst du die gemeinsamen Teile in eine Oberklasse (Tier). Die Unterklassen Hund und Katze erben alles und ergänzen Eigenes. Es gilt die „ist-ein“-Beziehung: Ein Hund ist ein Tier.
Der Pfeil mit dem leeren Dreieck zeigt immer auf die Oberklasse. In Java schreibst du extends und rufst den Konstruktor der Oberklasse mit super auf:
public class Medium {
protected String titel;
protected String signatur;
public Medium(String titel, String signatur) {
this.titel = titel;
this.signatur = signatur;
}
}
public class Buch extends Medium {
private int seitenzahl;
public Buch(String titel, String signatur, int seitenzahl) {
super(titel, signatur);
this.seitenzahl = seitenzahl;
}
}
protected erlaubt den Zugriff in der Klasse selbst und in ihren Unterklassen.
Eine abstrakte Klasse ist eine Oberklasse, von der es keine eigenen Objekte geben soll, etwa Form: Es gibt keine „Form an sich“, nur Kreise oder Quadrate. Sie darf abstrakte Methoden enthalten, die nur einen Kopf, aber keinen Rumpf haben. Jede nicht abstrakte Unterklasse muss sie ausprogrammieren. new Form() ist verboten, weil unklar wäre, was flaeche() berechnen soll.
Die Klasse Tier hat die Unterklassen Hund und Katze. a) Zeichnen Sie das Vererbungsdiagramm. b) Erklären Sie, was Vererbung bedeutet, und nennen Sie ein Attribut, das in…
Die Klasse Tier hat die Unterklassen Hund und Katze.
- a) Zeichnen Sie das Vererbungsdiagramm.
- b) Erklären Sie, was Vererbung bedeutet, und nennen Sie ein Attribut, das in
Tierstehen sollte.
Eine Bibliothek verwaltet Medien: Bücher (mit Seitenzahl) und DVDs (mit Spieldauer). Beide haben Titel und Signatur. a) Entwerfen Sie ein Klassendiagramm mit Oberklasse…
Eine Bibliothek verwaltet Medien: Bücher (mit Seitenzahl) und DVDs (mit Spieldauer). Beide haben Titel und Signatur.
- a) Entwerfen Sie ein Klassendiagramm mit Oberklasse
Medium.
- b) Schreiben Sie die Java-Klassen
MediumundBuchmit Konstruktoren (Aufrufsuper).
Polymorphie und dynamisches Binden
Eine Variable vom Typ der Oberklasse darf auf Objekte von Unterklassen zeigen. Welche Methode bei einem Aufruf läuft, entscheidet erst zur Laufzeit der tatsächliche Objekttyp: dynamisches Binden. Das ist Polymorphie („Vielgestaltigkeit“): derselbe Aufruf, je nach Objekt anderes Verhalten.
Ein schwierigerer Fall: Eine Methode der Oberklasse ruft eine Methode auf, die in der Unterklasse überschrieben wurde.
class A { String wer(){ return "A"; }
String hallo(){ return "Hallo " + wer(); } }
class B extends A { String wer(){ return "B"; } }
// A x = new B(); System.out.println(x.hallo());
hallo() wird von A geerbt, aber der Aufruf wer() geht an das tatsächliche Objekt, ein B. Ausgabe: „Hallo B“.
Wäre wer() in A private, könnte B sie weder sehen noch überschreiben. B.wer() wäre eine neue, unabhängige Methode. hallo() würde dann A.wer() nutzen: „Hallo A“.
Nutzen: Neue Unterklassen (z. B. Tretroller) lassen sich ergänzen, ohne dass der Code, der mit Form oder Fahrzeug arbeitet, geändert wird. Die Software ist leichter erweiterbar und wartbar.
a) Erklären Sie, warum new Form() nicht erlaubt ist. b) Berechnen Sie die Summe der Flächen für Form[] f = { new Kreis(1), new Quadrat(2) }; auf zwei Nachkommastellen…
abstract class Form { abstract double flaeche(); }
class Kreis extends Form {
double r;
Kreis(double r){ this.r = r; }
double flaeche(){ return Math.PI * r * r; }
}
class Quadrat extends Form {
double a;
Quadrat(double a){ this.a = a; }
double flaeche(){ return a * a; }
}
- a) Erklären Sie, warum
new Form()nicht erlaubt ist.
- b) Berechnen Sie die Summe der Flächen für
Form[] f = { new Kreis(1), new Quadrat(2) };auf zwei Nachkommastellen genau.
- c) Erläutern Sie, wo hier Polymorphie auftritt.
a) Geben Sie die Ausgabe von A x = new B(); System.out.println(x.hallo()); an und begründen Sie sie (dynamisches Binden). b) Erklären Sie, wie sich die Ausgabe ändert,…
class A { String wer(){ return "A"; } String hallo(){ return "Hallo " + wer(); } }
class B extends A { String wer(){ return "B"; } }
- a) Geben Sie die Ausgabe von
A x = new B(); System.out.println(x.hallo());an und begründen Sie sie (dynamisches Binden).
- b) Erklären Sie, wie sich die Ausgabe ändert, wenn
wer()inAalsprivatedeklariert wäre, und warumB.wer()dann keine Überschreibung ist.
- c) Beurteilen Sie den Nutzen von Polymorphie für die Erweiterbarkeit von Software.
Assoziationen und Multiplizitäten
Objekte stehen auch in Beziehung, ohne dass eine Vererbung vorliegt: Ein Kurs hat einen Lehrer und Schüler. Das ist eine Assoziation, eine Linie zwischen Klassen. An den Enden stehen Multiplizitäten: wie viele Objekte beteiligt sind (1, 0..1, * für beliebig viele, 1..*).
Lies die Multiplizitäten so: Die Assoziation Kurs–Lehrer hat am Lehrer die Multiplizität 1 (ein Kurs hat genau einen Lehrer) und am Kurs die Multiplizität * (ein Lehrer unterrichtet beliebig viele Kurse). Die Assoziation Kurs–Schueler hat an beiden Enden *: Ein Kurs hat viele Schüler, und ein Schüler besucht viele Kurse (n:m-Beziehung, denn in der Oberstufe wählt jeder Schüler mehrere Kurse).
In Java wird die Assoziation als Attribut umgesetzt: Bei Multiplizität 1 ein Attribut vom Typ der anderen Klasse, bei * eine Sammlung:
public class Kurs {
private Lehrer lehrer;
private ArrayList<Schueler> schueler = new ArrayList<>();
}
Ein Schulverwaltungsprogramm hat die Klassen Person (name), Schueler (klasse) und Lehrer (kuerzel). Ein Kurs hat genau einen Lehrer und viele Schüler. Ein Schüler kann…
Ein Schulverwaltungsprogramm hat die Klassen Person (name), Schueler (klasse) und Lehrer (kuerzel). Ein Kurs hat genau einen Lehrer und viele Schüler. Ein Schüler kann mehrere Kurse besuchen, und ein Lehrer kann mehrere Kurse unterrichten.
- a) Zeichnen Sie ein UML-Diagramm mit Vererbung und Assoziationen samt Multiplizitäten.
- b) Geben Sie an, wie die Assoziation
Kurs–Schuelerin Java als Attribut umgesetzt wird.
Entwurf, Klassenbibliotheken und Testen
Zurück zur Kölner Verkehrssimulation: Alle Fahrzeuge haben Position und Geschwindigkeit und müssen sich bewegen, aber jede Art anders. Das ergibt eine abstrakte Oberklasse Fahrzeug mit der abstrakten Methode bewege(). Abstrakt ist bewege(), weil es für „ein Fahrzeug“ keine sinnvolle Bewegung gibt. Bus ergänzt Haltestellen.
public abstract class Fahrzeug {
private double position;
private double geschwindigkeit;
public double getPosition() { return position; }
protected void setPosition(double p) { position = p; }
public double getGeschwindigkeit() { return geschwindigkeit; }
public abstract void bewege();
}
public class Auto extends Fahrzeug {
public void bewege() {
setPosition(getPosition() + getGeschwindigkeit());
}
}
Da die Attribute privat sind, kann nur die Klasse selbst Position und Geschwindigkeit ändern. Fehlerhafte Werte werden an einer Stelle abgefangen, und Fehler in der Simulation lassen sich schnell eingrenzen.
Klassenbibliotheken wie java.util.ArrayList<E> bieten fertige, getestete Klassen. Vorteile: weniger Programmieraufwand, weniger Fehler, einheitliche Schnittstellen, gute Dokumentation, hohe Wartbarkeit.
Systematisch testen heißt: vorher Testfälle mit erwarteten Ergebnissen festlegen und Normalfälle, Grenzfälle (leer, ein Element) und Sonderfälle abdecken. Dann Ergebnis und Erwartung vergleichen.
Ein Verkehrssimulationsprogramm für Köln soll Fahrzeuge (Auto, Bus, Fahrrad) verwalten. Jedes Fahrzeug hat Position und Geschwindigkeit und muss sich in jedem…
Ein Verkehrssimulationsprogramm für Köln soll Fahrzeuge (Auto, Bus, Fahrrad) verwalten. Jedes Fahrzeug hat Position und Geschwindigkeit und muss sich in jedem Zeitschritt bewegen; die Bewegung unterscheidet sich je Typ. Busse halten zusätzlich an Haltestellen.
- a) Entwerfen Sie eine Klassenhierarchie mit abstrakter Oberklasse und begründen Sie, was abstrakt ist.
- b) Schreiben Sie Java-Code für die abstrakte Klasse und eine Unterklasse mit der Methode
bewege().
- c) Begründen Sie, wie Kapselung (private Attribute, Getter) Fehler in der Simulation vermeiden hilft.
Gegeben ist die Klassenbibliothek java.util.ArrayList<Schueler>. Die Klasse Schueler besitzt eine Methode double getNote(). a) Schreiben Sie eine Methode double…
Gegeben ist die Klassenbibliothek java.util.ArrayList<Schueler>. Die Klasse Schueler besitzt eine Methode double getNote().
- a) Schreiben Sie eine Methode
double durchschnitt(ArrayList<Schueler> liste), die den Durchschnitt vongetNote()berechnet und den Fall der leeren Liste behandelt. Begründen Sie Ihre Entscheidung für das Verhalten bei leerer Liste (z. B. Rückgabewert $0{,}0$,Double.NaNoder Auslösen einer Ausnahme).
- b) Erläutern Sie Vorteile der Wiederverwendung von Klassenbibliotheken.
- c) Beschreiben Sie, wie Sie die Methode systematisch testen (mindestens vier Testfälle mit erwarteten Ergebnissen).
Vor der Zusammenfassung zurück zum Anfang: Mit einer abstrakten Oberklasse Fahrzeug und der Methode bewege() kann die Simulation alle Fahrzeuge gleich behandeln. Neue Typen kommen als Unterklassen hinzu.
Auf einen Blick
-
Eine Klasse ist der Bauplan (Attribute, Methoden), ein Objekt ein Exemplar mit eigenem Zustand.
-
Kapselung: Attribute
private, Zugriff überpublicMethoden mit Prüfungen. -
Vererbung (
extends,super) gilt bei „ist-ein“; abstrakte Klassen haben keine eigenen Objekte und schreiben Methoden vor. -
Polymorphie: Das dynamische Binden wählt zur Laufzeit die Methode des tatsächlichen Objekts. Private Methoden werden nicht überschrieben.
-
Assoziationen werden mit Multiplizitäten (
1,*,0..1) modelliert und in Java als Attribute oderArrayListumgesetzt. -
Klassenbibliotheken sparen Aufwand; systematisches Testen nutzt Normal-, Grenz- und Sonderfälle.