Programming lesson
Vererbung und Polymorphie in Java: Eine praxisnahe Anleitung mit MyMusicApp
Lerne Vererbung und Polymorphie in Java anhand der MyMusicApp – inklusive Subklassen für Musikgenres, überschriebene Methoden und typische Fallstricke. Ideal für ICS 141.
Vererbung und Polymorphie in Java verstehen – mit der MyMusicApp
Die Konzepte Vererbung und Polymorphie sind zentrale Säulen der objektorientierten Programmierung (OOP). In diesem Tutorial zeige ich dir, wie du diese Prinzipien in Java anwendest – und zwar anhand der MyMusicApp, einem Projekt aus dem Kurs ICS 141 – 02. Egal, ob du gerade deine ersten Schritte in Java machst oder dein Wissen vertiefen möchtest: Diese Anleitung hilft dir, die Theorie hinter Vererbung und Polymorphie praktisch umzusetzen. Stell dir vor, du entwickelst eine Playlist-App, die verschiedene Musikgenres wie Pop, Jazz oder Rock verwaltet – genau das werden wir tun.
Was ist Vererbung?
Vererbung erlaubt es einer Klasse (Subklasse), Eigenschaften und Methoden einer anderen Klasse (Superklasse) zu übernehmen. In unserem Fall ist Music die Superklasse. Sie enthält grundlegende Attribute wie Titel, Künstler und Lautstärke. Die Subklassen, z. B. Pop, Jazz oder Rock, erben diese Eigenschaften und fügen eigene hinzu – etwa die Stimmung eines Songs oder die BPM-Zahl. Das spart Code und sorgt für eine logische Hierarchie.
Polymorphie: Einheitlich ansprechen, unterschiedlich verhalten
Polymorphie bedeutet „Vielgestaltigkeit“. Du kannst ein Objekt einer Subklasse über eine Referenz der Superklasse ansprechen und trotzdem die überschriebenen Methoden der Subklasse aufrufen. Ein Beispiel: Wenn du eine Methode increaseVolume() in der Superklasse definierst und in jeder Subklasse anders implementierst, wird beim Aufruf über die Superklassen-Referenz die richtige Version ausgeführt. Das ist besonders nützlich, wenn du eine Liste von Musikstücken verschiedener Genres hast und alle gleich behandeln möchtest.
Unser Projekt: MyMusicApp
Die Aufgabe aus Assignment 4 besteht darin, die bereitgestellte Music-Klasse zu erweitern. Du erstellst zwei Subklassen für unterschiedliche Genres, überschreibst die toString()-Methode und fügst eine Methode nameThatTune() hinzu. Ein PlaylistDriver testet die Funktionalität und zeigt, was bei polymorphen Aufrufen passiert. Klingt machbar? Legen wir los.
Schritt 1: Die Superklasse Music verstehen
Lade das MyMusicApp-Projekt herunter (z. B. aus D2L) und importiere es in Eclipse. Sieh dir die Music-Klasse an: Sie enthält Instanzvariablen wie title, artist und volume sowie Methoden wie increaseVolume() und toString(). Deine erste Aufgabe ist es, eine toString()-Methode hinzuzufügen, falls sie noch nicht existiert. Diese Methode gibt alle Informationen des Songs als lesbaren String zurück.
public class Music {
private String title;
private String artist;
private int volume;
public Music(String title, String artist, int volume) {
this.title = title;
this.artist = artist;
this.volume = volume;
}
public String getTitle() { return title; }
public String getArtist() { return artist; }
public int getVolume() { return volume; }
public void increaseVolume() {
if (volume < 100) volume += 10;
}
@Override
public String toString() {
return "Music [title=" + title + ", artist=" + artist + ", volume=" + volume + "]";
}
}Schritt 2: Subklassen erstellen – Pop und Jazz
Wähle zwei Genres, z. B. Pop und Jazz. Jede Subklasse muss die Superklasse Music mit extends erweitern. Füge 2–3 zusätzliche Variablen hinzu, die für das Genre typisch sind. Für Pop könnten das mood (Stimmung) und danceability (Tanzbarkeit) sein, für Jazz improvisation (Improvisationsgrad) und instrumentation (Instrumentierung).
Pop-Klasse
public class Pop extends Music {
private String mood;
private int danceability;
public Pop(String title, String artist, int volume, String mood, int danceability) {
super(title, artist, volume);
this.mood = mood;
this.danceability = danceability;
}
@Override
public void increaseVolume() {
// Pop wird oft lauter gehört – erhöhe um 15 statt 10
if (getVolume() < 100) setVolume(getVolume() + 15);
}
public String nameThatTune() {
return getTitle();
}
@Override
public String toString() {
return super.toString() + " Pop [mood=" + mood + ", danceability=" + danceability + "]";
}
}Jazz-Klasse
public class Jazz extends Music {
private int improvisation;
private String instrumentation;
public Jazz(String title, String artist, int volume, int improvisation, String instrumentation) {
super(title, artist, volume);
this.improvisation = improvisation;
this.instrumentation = instrumentation;
}
@Override
public void increaseVolume() {
// Jazz wird oft leiser gehört – erhöhe nur um 5
if (getVolume() < 100) setVolume(getVolume() + 5);
}
public String nameThatTune() {
return getTitle();
}
@Override
public String toString() {
return super.toString() + " Jazz [improvisation=" + improvisation + ", instrumentation=" + instrumentation + "]";
}
}Schritt 3: Den PlaylistDriver schreiben
Der Driver testet die Objekte und zeigt Polymorphie in Aktion. Er erzeugt je ein Objekt von Music, Pop und Jazz. Dann ruft er alle Methoden auf und dokumentiert Fehler.
public class PlaylistDriver {
public static void main(String[] args) {
// Objekte erzeugen
Music music = new Music("Generic Song", "Unknown", 50);
Pop pop = new Pop("Blinding Lights", "The Weeknd", 70, "Energetic", 80);
Jazz jazz = new Jazz("Take Five", "Dave Brubeck", 40, 9, "Saxophone, Piano");
// Methoden aufrufen
System.out.println(music.toString());
music.increaseVolume();
System.out.println("Volume after increase: " + music.getVolume());
System.out.println(pop.toString());
pop.increaseVolume();
System.out.println("Pop volume: " + pop.getVolume());
System.out.println("Pop tune: " + pop.nameThatTune());
System.out.println(jazz.toString());
jazz.increaseVolume();
System.out.println("Jazz volume: " + jazz.getVolume());
System.out.println("Jazz tune: " + jazz.nameThatTune());
// Polymorphie: Music-Referenz auf Pop-Objekt
Music musicRef = new Pop("Levitating", "Dua Lipa", 80, "Happy", 90);
System.out.println(musicRef.toString()); // ruft Pop.toString() auf
musicRef.increaseVolume(); // ruft Pop.increaseVolume() auf
// musicRef.nameThatTune(); // FEHLER: Methode existiert nicht in Music
// musicRef.getMood(); // FEHLER: Methode existiert nicht in Music
// Polymorphie: Pop-Referenz auf Music-Objekt
// Pop popRef = new Music("Test", "Test", 50); // FEHLER: Music ist nicht Pop
// Array mit verschiedenen Typen
Music[] playlist = { music, pop, jazz };
for (Music m : playlist) {
System.out.println(m.toString());
m.increaseVolume(); // ruft die überschriebene Methode auf
}
}
}Häufige Fehler und wie du sie vermeidest
- Fehler beim Überschreiben: Achte auf die genaue Methodensignatur. Ein Tippfehler führt dazu, dass die Methode nicht überschrieben wird.
- Vergessene
super()-Aufrufe: Der Konstruktor der Subklasse musssuper(parameter)aufrufen, sonst gibt es einen Compilerfehler. - Polymorphie-Fallen: Wenn du eine Subklassen-spezifische Methode über eine Superklassen-Referenz aufrufen willst, musst du casten – aber nur, wenn das Objekt wirklich von der Subklasse ist.
Trends & Praxisbezug
Vererbung und Polymorphie begegnen dir nicht nur in der Uni. Stell dir vor, du entwickelst eine App wie Spotify oder Apple Music. Die Klassenstruktur ähnelt unserem Beispiel: Eine Superklasse Song mit Subklassen für verschiedene Genres. Oder du programmierst ein KI-gestütztes Musikempfehlungssystem, das je nach Genre unterschiedliche Algorithmen nutzt – auch hier helfen Polymorphie und Vererbung. Selbst in der Spieleentwicklung (z. B. mit Unity) werden solche Konzepte genutzt, um verschiedene Gegnertypen zu modellieren. Wenn du diese Prinzipien beherrschst, bist du bestens gerüstet für deine Java-Programmieraufgaben und echte Projekte.
Fazit
Mit Vererbung und Polymorphie sparst du Zeit und machst deinen Code wartbarer. Die MyMusicApp ist ein perfektes Übungsbeispiel für ICS 141. Denk daran: Kommentiere deinen Code, achte auf konsistente Einrückungen und dokumentiere Fehler. Viel Erfolg bei deiner Assignment 4 – und vergiss nicht, dein Video aufzunehmen!