Koordinatengrafik mit Java
HomeAufgabenDruckenJava-Online

Komposition und Vererbung

Komplexe Probleme werden beim Programmieren oft in einfachere Teilprobleme unterteilt. Eine bekannte Programmiertechnik besteht darin, das Programm in mehrere Methoden zu strukturien (Strukturierte oder Prozedurale Programmierung). Eine neuere Programmiertechnik teilt zudem das Programm in mehrere Klassen auf, die den unterschiedlichen Daten angepasst sind (Objektorientierte Programmierung). Eine Klasse legt Eigenschaften und Verhalten von Objekten fest. Ein Java-Programm besteht daher in der Regel aus mehreren Klassen. Ein grosser Vorteil dieser Programmiertechnik liegt darin, dass einmal programmierte Klassen mehrmals, sowohl in der aktuellen, wie auch in anderen Applikationen, verwendet werden können.
Es gibt grundsätzlich zwei Arten, wie diese Klassen zusammenhängen können:

Komposition

Bei der Komposition delegiert die Hauptklasse Eigenschaften und Verhalten an ihre Komponentenklassen.

Im Beispiel 1 enthält die Klasse Moire eine Instanz von GPanel. Das Zeichnen der Linien wird an GPanel delegiert.

// MoireHas.java

import ch.aplu.util.*;

public class MoireHas
{
  private GPanel p = new GPanel(010010)// GPanel is part of Moire
  
  public MoireHas()
  {
    int i, k;
    for (= 0; i <= 10; i++)
    {
      for (= 0; k <=10; k++)
        p.line(i, 0, k, 10);
    }
    
    for (= 0; i <= 10; i++)
    {
      for (= 0; k <= 10; k++)
        p.line(0, i, 10, k);
    }
  }

  public static void main(String[] args)
  {
    new MoireHas();
  }
}

 

 

 

 

 

 

Erklärungen zum Programmcode:
Bei Programmen, die mehrere Klassen enthalten, müssen alle Klassen im gleichen Online-Editor-Fenster (in der selben Datei) eingegeben werden. Dabei ist darauf zu achten, dass die Haupklasse, (diejenige, die main() enthält) vor allen anderen Klassen deklariert wird, weil der Online-Editor automatisch aus der obersten Klasse den Applikationsnamen erzeugt.

Im Beispiel 2 wird das Zeichnen eines Sternes an die Klasse Star delegiert. Beim Instanzieren der Klasse wird die Grösse und die Farbe des Sterns festgelegt. Die Methode draw() zeichnet den Stern an der gewünschten Stelle. Das Programm zeichnet 12 kreisartig angeordnette Sterne.

// KompositionEx2.java

import ch.aplu.util.*;
import java.awt.Color;


public class KompositionEx2 
{
  private GPanel p = new GPanel();
  private Star s = new Star(0.05);  
    
  public KompositionEx2()
  {
    double x;
    double y;
    p.bgColor(Color.blue);
    for (int i = 0; i < 12; i++)
    {
      x = 0.5 + 0.3 * Math.cos(Math.PI/6 * i);
      y = 0.5 + 0.3 * Math.sin(Math.PI/6 * i);
      s.draw(x, y);   
    }
  } 
  
  
  // ------------------ class Star ---------------
  class Star
  {
    private double size;
     
    Star(double size)
    {
      this.size = size;  // kopiert den Parameter size 
                         // in die Instanzvariable size
      p.color(Color.yellow);    
    }    
    
    void draw(double x, double y)
    {
      p.fillTriangle(- Math.sqrt(3)/2 * size, y - size/2,
                 x + Math.sqrt(3)/2 * size, y - size/2,
                 x, y + size);
      p.fillTriangle(- Math.sqrt(3)/2 * size, y + size/2,
                 x + Math.sqrt(3)/2 * size, y + size/2,
                 x, y - size);
    }             
  }
  
  public static void main(String[] args)
  {
    new KompositionEx2();
  }
}

 

 

 

 

 

 

 

Erklärungen zu Programmcode
Der Stern besteht aus zwei gefüllten Dreiecken.

Es wird eine innere Klasse verwendet, damit diese problemlos Zugriff auf das GPanel besitzt.


Beispiel 3: Ampelanlage

// Ampelanlage.java

import ch.aplu.util.*;
import java.awt.*;

public class Ampelanlage
{
  GPanel p = new GPanel(01000100);
  
  Ampelanlage()
  {
    Ampel a = new Ampel(2050);
    a.setState(0);
    Ampel b = new Ampel(8050);
    b.setState(2);
    p.pos(505);
    p.color(Color.black);
    p.text("Beliebige Taste drücken");
    while (true)
    {
      p.getKeyWait();
      a.nextState();
      b.nextState();
    }
  }

  class Ampel
  {
    final double width = 30;
    final double height = 60;

    private Lampe red;
    private Lampe yellow;
    private Lampe green;
    private int stateNb = 0;

    Ampel(double xPos, double yPos)
    {
      p.color(Color.darkGray);
      p.pos(xPos, yPos);
      p.fillRectangle(width, height);
      red = new Lampe(xPos, yPos + height / 3Color.red, Color.black);
      yellow = new Lampe(xPos, yPos, Color.yellow, Color.black);
      green = new Lampe(xPos, yPos - height / 3Color.green, Color.black);
    }

    public void setState(int state)
    {
      stateNb = state;
      showState();
    }

    public void nextState()
    {
      stateNb = (stateNb + 1) % 4;
      showState();
    }

    public void showState()
    {
      switch (stateNb)
      {
        case 0:
          red.turnOn(true);
          yellow.turnOn(false);
          green.turnOn(false);
          break;

        case 1:
        case 3:
          red.turnOn(false);
          yellow.turnOn(true);
          green.turnOn(false);
          break;

        case 2:
          red.turnOn(false);
          yellow.turnOn(false);
          green.turnOn(true);
          break;
      }
    }
  }

  class Lampe
  {
    final double radius = 8;

    private double x;
    private double y;
    private Color onC;
    private Color offC;

    Lampe(double xPos, double yPos, Color onColor, Color offColor)
    {
      x = xPos;
      y = yPos;
      onC = onColor;
      offC = offColor;
    }

    public void turnOn(boolean on)
    {
      if (on)
      {
        p.color(onC);
      }
      else
      {
        p.color(offC);
      }
      p.pos(x, y);
      p.fillCircle(radius);
    }
  }

  public static void main(String[] args)
  {
    new Ampelanlage();
  }
}