Koordinatengrafik mit Java
HomeAufgabenDruckenJava-Online

Polymorphismus

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.

 Beispiel 6: Wir deklarieren eine Klasse StarPanel mit der Methode draw(). Diese zeichnet ein Sternenbanner. Vom StarPanel wird die Klasse YellowSky abgeleitet, welche die Methode draw() überschreibt. Diese zeichnet einen Himmel mit gelben Sternen. Die Klasse BlueSky überschreibt ebenfalls die Methode draw() vom StarPanel. Sie zeichnet einen Himmel mit blauen Sternen.
Nach dem Programmstart kann gewählt werden, ob ein Objekt der Klasse StarPanel, YellowSky oder BlueSky erzeugt werden soll. Entsprechend zu dieser Wahl wird dann die passende Methode draw() aufgerufen.

 
// 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(- Math.sqrt(3)/2 * r, y - r/2,
                 x + Math.sqrt(3)/2 * r, y - r/2,
                 x, y + r);
    fillTriangle(- 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(- Math.sqrt(3)/2 * r, y - r/2,
                 x + Math.sqrt(3)/2 * r, y - r/2,
                 x, y + r);
    fillTriangle(- 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