Zurück   Weiter

8 Interfaces und abstrakte Klassen

8.1 Interfaces

In Java gibt es keine Mehrfachvererbung. Statt dessen kennt Java die Interfaces. Wie der Name bereits andeutet, sind Interfaces reine Schnittstellen, die keinerlei Implementierung enthalten. Jede Klasse kann ein oder auch mehrere Interfaces einbinden, dies bedeutet, die Schnittstellen zu implementieren. Bei einer solchen Klasse kann auf die Methoden und Datenfelder des Interfaces zugegriffen werden, als sei diese Klasse Subklasse des Interfaces. In Interfaces werden Methoden nur mit Returntyp, Name und Parameterliste definiert, aber keine Funktionalität implementiert, das heisst kein Anwendungsblock definiert. Diese Methoden nennt man abstract. Die Angabe von abstract ist bei Methoden einer interface-Definition nicht nötig. Alle Methoden eines Interfaces sind implizit abstract. Ebenso können in einem Interface Konstanten definiert werden. Alle in Interfaces vereinbarten Datenfelder sind auch ohne Angabe von Modifier als final definiert und damit Konstanten.

8.1.1 Definition eines Interfaces

  interface SchnittstellenName {
    ...
    ...
  }

Die Definition eines Interfaces ist gleich aufgebaut, wie die Definition einer Klasse. Das Schlüsselwort class wird hierbei durch das Schlüsselwort interface ersetzt. Im folgenden Anweisungsblock stehen die Methoden- und Konstantendefintionen.

  interface KlassenName {
    variablenTyp konstante1 = wert1;
    variablenTyp konstante2 = wert2;
    ...

    returnTyp methodenName1(ParameterListe1);
    void methodenName2(ParameterListe2);
    ...
  }

Die Zugriffsklassen gelten analog den Zugriffsklassen von Klassendefinitionen. Ausnahme ist der Modifier private, welcher in Interfaces nicht erlaubt ist. Auch bei Interfaces gilt, das als public definierte Interfaces in Dateien stehen müssen, die den selben Namen besitzen, wie das in ihnen definierte Interface.

package graphic;

public interface Paintable1 {
  public void paint();
}

Sourcefile

8.1.2 Implementierung eines Interface

Zur Implementierung eines Interfaces wird im Kopf der Klassendefinition das Schlüsselwort implements und der oder die Namen des Interfaces angegeben.

  class KlassenName extends SuperKlasse implements Interface1, Interface2, ..., InterfaceN{
    ...
  }

Eine Klasse, welche ein Interface implementiert muss alle im Interface definierten Methoden überschreiben.

  class KlassenName extends SuperKlasse implements Interface1 {
    ...
    returnTyp interFaceMethode1(ParameterListe1) {
      ...
    }

    returnTyp interFaceMethode2(ParameterListe2) {
      ...
    }
    ...
    returnTyp interFaceMethodeN(ParameterListeN) {
      ...
    }
  }

Nach der Implementierung eines Interfaces kann eine Klasse wie eine Subklasse des Types Interface behandelt werden. Das bedeutet, dass auch Variablen den Typ eines Interfaces besitzen können. Eine Zuweisung ist dann erlaubt, wenn die zugewiesene Instanz das Interface implementiert.

  class Klasse_1 {
    ...
  }

  interface Interface_1 {
    ...
  }

  class Klasse_2 implements Interface_1 {
    ...
  }

  class KlassenName {
    ...

    returnTyp methodenName(ParameterListe) {
      ...
      Interface_1 a;
      ...
      // Die folgende Zuweisung ist erlaubt.
      a = new Klasse_2();
      ...
      // Die folgende Zuweisung ist nicht erlaubt.
      a = new Klasse_1();
      ...
    }

    ...
  }

Line6.java

package graphic;

public class Line6 implements Paintable1 {
  private Point15 start;
  private Point15 end;

  public Line6(Point15 p1, Point15 p2) {
    start = p1;
    end = p2;
  }

  public void paint() {
    int minY;
    int maxY;
    if(start.getYPosition() > end .getYPosition()) {
      minY = end.getYPosition();
      maxY = start.getYPosition();
    } else {
      minY = start.getYPosition();
      maxY = end.getYPosition();
    }
    double m = (end.getYPosition() - start.getYPosition()) /
               (double)(end.getXPosition() - start.getXPosition());
    double b = -m * end.getXPosition() + end.getYPosition();
    for(int i = 0; i < minY; i++) {
      System.out.println();
    }
    for(int i = minY; i <= maxY; i++) {
      int xPos = (int)Math.round(1/m * (i - b));
      for(int j = 0; j < xPos; j++) {
        System.out.print(" ");
      }
      System.out.println("x");
    }
  }
}

Sourcefile

Rectangle1.java

package graphic;

public class Rectangle1 implements Paintable1 {
  Point15 insertPoint;
  int width;
  int height;

  public Rectangle1(Point15 insertPoint, int width, int height) {
    this.insertPoint = insertPoint;
    this.width = width;
    this.height = height;
  }

  public void paint() {
    for(int i = 0; i < insertPoint.getYPosition(); i++) {
      System.out.println();
    }
    for(int i = 0; i < insertPoint.getXPosition(); i++) {
      System.out.print(" ");
    }
    for(int i = insertPoint.getXPosition(); i < insertPoint.getXPosition() + width;i++) {
      System.out.print("x");
    }
    System.out.println();
    for(int i = insertPoint.getYPosition(); i < insertPoint.getYPosition() + height - 2; i++) {
      for(int j = 0; j < insertPoint.getXPosition(); j++) {
        System.out.print(" ");
      }
      System.out.print("x");
      for(int j = insertPoint.getXPosition() + 1; j < insertPoint.getXPosition() + width - 1; j++) {
        System.out.print(" ");
      }
      System.out.print("x");
      System.out.println();
    }
    for(int i = 0; i < insertPoint.getXPosition(); i++) {
      System.out.print(" ");
    }
    for(int i = insertPoint.getXPosition(); i < insertPoint.getXPosition() + width;i++) {
      System.out.print("x");
    }
    System.out.println();
  }
}

Sourcefile

Paint10.java

import graphic.Line6;
import graphic.Paintable1;
import graphic.Point15;
import graphic.Rectangle1;

public class Paint10 {
  public static void main(String[] args) {
    Point15 a = new Point15(1, 3);
    Point15 b = new Point15(5, 7);
    Paintable1[] paintObjects = new Paintable1[2];
    paintObjects[0] = new Line6(a, b);
    Point15 c = new Point15(1, 3);
    paintObjects[1] = new Rectangle1(c, 4, 3);
    for(int i = 0; i < paintObjects.length; i++) {
      paintObjects[i].paint();
    }
  }
}
Sourcefile

Auf diese Weise lassen sich beliebig viele verschiedene Paintable1-Objekte erzeugen, welche alle die Methode paint besitzen. Das Zeichenprogramm muss die einzelnen Objekte nicht kennen. Zum Zeichnen reicht das kennen dieser Methode aus.

Aufgabe 20

8.1.3 Vererbung bei Interfaces

Interfaces werden ebenso wie die Klassen mit extends vererbt. Im Unterschied zu Klassen, kann ein Interface aber von mehreren Interfaces erben. Eine Klasse die ein Interface implementiert, welches von anderen Interfaces erbt, muss die Methoden des Interfaces und aller beerbten Interfaces implementieren.

  interface Interface_1 {
    ...
  }

  interface Interface_2 {
    ...
  }

  interface Interface_3 {
    ...
  }

  class KlasseName implements Interface_3 {
    ...
  }

8.2 Abstrakte Klassen

Bei abstrakten Klassen wird dem Schlüsselwort class, das Schlüsselwort abstract vorangestellt. Von abstrakten Klassen können keine Instanzen erzeugt werden, sie können nur als Superklassen verwendet werden. Abstrakte Klassen können abstrakte Methoden enthalten, welche von den beerbten Klassen implementiert werden müssen. Anders als die Interfaces können abstrakte Klassen aber schon eigene Implementierungen von Methoden enthalten. Als Beispiel ändern wir das Interface Paintable in eine abstrakte Klasse um. Jedes Paintable-Objekt wird um die Möglichkeit Paintable.java

package graphic;

public abstract class Paintable {
  private Point paintPosition;

  public void setPaintPosition(Point PaintPosition) {
    this.paintPosition = paintPosition;
  }

  public void paint() {
    paint(paintPosition);
  }

  protected abstract void paint(Point paintPosition);
}

Line.java

package graphic;

public class Line extends Paintable {
  private Point start;
  private Point end;

  public Line(Point p1, Point p2) {
    start = p1;
    end = p2;
  }

  public void paint() {
    System.out.println("Linie zeichnen von Punkt(" + start.getXPosistion() +
                       ", " + start.getYPosition() + ")");
    System.out.println("nach Punkt(" + end.getXPosition() + ", " +
                       end.getYPosition() + ").");
  }
}

PaintProgram.java

import graphic.Line;
import graphic.Paintable;
import graphic.Point;

public class PaintProgram {
  public static void main(String[] args) {
    Point a = new Point(1, 3);
    Point b = new Point(5, 7);
    Paintable graph = new Line(a, b);
    graph.paint();
    b.moveTo(2, 5);
    graph.paint();
  }
}
Created with Vim Zurück   Weiter