Unter Polymorphismus versteht man beim objektorientierten Programmieren das Binden von Methodenaufrufen zur Laufzeit und nicht, wie üblich, zur Kompilationszeit. Erst zur Laufzeit wird dynamisch die entsprechende Methode, passend zum tatsächlich verwendeten Objekt, ausgewählt.
|
![]() |
// VererbungEx6.java import ch.aplu.util.*; import java.awt.Color; public class VererbungEx6 { public VererbungEx6() { StarPanel sp = null; InputDialog id = new InputDialog ("Farbe", "Geben Sie 1, 2 oder 3 ein: "); int index = id.readInt(); switch(index) { case 1: sp = new YellowSky(); break; case 2: sp = new BlueSky(); break; case 3: sp = new StarPanel(); break; } // welches draw()??? // StarPanel's oder YellowSky's oder BlueSky's? // Zur Zeit der Compilierung ist nicht bekannt welches draw()gewählt wird // erst zur Laufzeit wird dynamisch die passende Methode gewählt sp.draw(); } public static void main(String[] args) { new VererbungEx6(); } } // ------------------- class StarPanel --------------------- class StarPanel extends GPanel { public void drawStar(double x, double y) { double r = 0.05; fillTriangle(x - Math.sqrt(3)/2 * r, y - r/2, x + Math.sqrt(3)/2 * r, y - r/2, x, y + r); fillTriangle(x - Math.sqrt(3)/2 * r, y + r/2, x + Math.sqrt(3)/2 * r, y + r/2, x, y - r); } public void draw() { color(Color.red); double x; double y; for (int i = 0; i < 12; i++) { x = 0.5 + 0.3 * Math.cos(Math.toRadians(360/12) * i); y = 0.5 + 0.3 * Math.sin(Math.toRadians(360/12) * i); drawStar(x, y); } } } // ------------------- class YellowSky --------------------- class YellowSky extends StarPanel { public void draw() { color(Color.yellow); double x, y; for (int i = 0; i < 50; i++) { x = Math.random(); y = Math.random(); drawStar(x, y); } } } // ------------------- class BlueSky ----------------------- class BlueSky extends StarPanel { public void draw() { color(Color.blue); double x, y; for (int i = 0; i < 50; i++) { x = Math.random(); y = Math.random(); drawStar(x, y); } } } |
|
|
Erklärungen zum Programmcode:
Die Variable sp ist als Typ der Basisklasse StarPanel deklariert. Trotzdem wird der Aufruf sp.draw() zur Kompilationszeit nicht mit draw() aus der Klasse StarPanel gebunden. Der Variabeln sp wird zur Laufzeit eine Referenz von YellowSky, BlueSky oder StarPanel zugewiesen. Da YellowSky bzw.BlueSky ebenfalls StarPanel sind, wird diese Zuweisung vom Compiler zugelassen. Erst zur Laufzeit wird das draw() der zugewiesenen Klasse aufgerufen.
Beispiel 7: Es gehört zur professionellen Programmierung, Eingabefehler abzufangen. Im Beispiel 7 wird die Eingabe in der Dialogbox überprüft. Falls eine andere Zahl als 1, 2, oder 3 eingegeben wird, erscheint eine Messagebox mit einer Fehlermeldung. Bei einer Eingabe, die nicht als Ganzzahl aufgefasst werden kann, fängt der InputDialog den Fehler selbst ab. Falls die Schaltfläche Abbrechen geklickt wird, wird die Dialogbox geschlossen.
// VererbungEx7.java import ch.aplu.util.*; import java.awt.Color; import javax.swing.JOptionPane; public class VererbungEx7 { public VererbungEx7() { StarPanel sp = null; boolean ok = false; Integer index = null; while (!ok) { InputDialog id = new InputDialog ("Farbe", "Geben Sie 1, 2 oder 3 ein: "); index = id.getInt(); if (index == null) System.exit(0); if (index.intValue() > 0 && index.intValue() < 4) ok = true; else JOptionPane.showMessageDialog(null, "Bitte 1, 2, oder 3 eingeben", "Falsche Eingabe", JOptionPane.ERROR_MESSAGE); } switch(index.intValue()) { case 1: sp = new YellowSky(); break; case 2: sp = new BlueSky(); break; case 3: sp = new StarPanel(); break; } // welches draw()??? // StarPanel's oder YellowSky's oder BlueSky's? // Zur Zeit der Compilierung ist nicht bekannt welches draw()gewählt wird // erst zur Laufzeit wird dynamisch die passende Methode gewählt sp.draw(); } public static void main(String[] args) { new VererbungEx7(); } } // ------------------- class StarPanel --------------------- class StarPanel extends GPanel { public void drawStar(double x, double y) { double r = 0.05; fillTriangle(x - Math.sqrt(3)/2 * r, y - r/2, x + Math.sqrt(3)/2 * r, y - r/2, x, y + r); fillTriangle(x - Math.sqrt(3)/2 * r, y + r/2, x + Math.sqrt(3)/2 * r, y + r/2, x, y - r); } public void draw() { color(Color.red); double x; double y; for (int i = 0; i < 12; i++) { x = 0.5 + 0.3 * Math.cos(Math.toRadians(360/12) * i); y = 0.5 + 0.3 * Math.sin(Math.toRadians(360/12) * i); drawStar(x, y); } } } // ------------------- class YellowSky --------------------- class YellowSky extends StarPanel { public void draw() { color(Color.yellow); double x, y; for (int i = 0; i < 50; i++) { x = Math.random(); y = Math.random(); drawStar(x, y); } } } // ------------------- class BlueSky ----------------------- class BlueSky extends StarPanel { public void draw() { color(Color.blue); double x, y; for (int i = 0; i < 50; i++) { x = Math.random(); y = Math.random(); drawStar(x, y); } } } |
|
|
Erklärungen zum Programmcode:
Um den Klick auf den Knopf Abbrechen abzufangen wird die Methode getInt() verwendet, die einen Referenztyp der Klasse Integer zurückgibt (nicht int). Drückt man Abbrechen, wird null zurückgegeben. Die Methode intValue() liefert den int-Wert.
Aufgaben zur Vererbung und Polymorphismus