Inselupdate: Vererbung und Überschattung von statischen Variablen

Die Konstanten einer Schnittstelle können einer anderen Schnittstelle vererbt werden. Dabei gibt es einige kleine Einschränkungen. Wir wollen an einem Beispiel sehen, wie sich die Vererbung auswirkt, wenn gleiche Bezeichner in den Unterschnittstellen erneut verwendet werden. Als Basis unseres Beispiels steht eine Schnittstelle BaseColors mit ein paar Deklarationen von Farben. Zwei Unterschnittstellen erweiterten BaseColor, einmal CarColors und PlaneColors, die für Farbdeklarationen für Autos und Flugzeuge stehen. Eine besondere Schnittstelle FlyingCarColors erweitert die beiden Schnittstelen CarColors und PlaneColors, denn es gibt auch fliegende Autos, die eine Farbe haben können.

interface BaseColors
{
  int WHITE   = 0;
  int BLACK   = 1;
  int GREY    = 2;
}

interface CarColors extends BaseColors
{
  int WHITE   = 1;
  int BLACK   = 0;
}

interface PlaneColors extends BaseColors
{
  int WHITE   = 0;
  int GREY    = 2;
}

interface FlyingCarColors extends CarColors, PlaneColors
{
}

public class Colors
{
  public static void main( String[] args )
  {
    System.out.println( BaseColors.GREY );      // 2
    System.out.println( CarColors.GREY );       // 2
    System.out.println( BaseColors.BLACK );     // 1
    System.out.println( CarColors.BLACK );      // 0
    System.out.println( PlaneColors.BLACK );    // 1

    System.out.println( FlyingCarColors.WHITE );//  The field FlyingCarColors.WHITE is ambiguous
    System.out.println( FlyingCarColors.GREY ); //  The field FlyingCarColors.GREY is ambiguous
  }
}

Die erste wichtige Tatsache ist, dass unsere drei Schnittstellen ohne Fehler übersetzt werden können, aber nicht die Klasse Colors. Das Programm und der Compiler zeigen folgendes Verhalten:

  • Schnittstellen vererben ihre Eigenschaften an die Unterschnittstellen. CarColors und auch PlaneColors erbten die Farbe WHITE, BLACK und GREY aus BaseColors.
  • Konstanten dürfen überschattet werden. CarColors vertauscht die Farbdeklarationen von WHITE und BLACK und gibt ihnen neue Werte. Wird jetzt der Wert CarColors.BLACK verlangt, liefert die Umgebung den Wert 0, während CarColors.BLACK 1 ergibt. Auch PlaneColor überdeckt die Konstanten WHITE und GREY obwohl sie Farbe mit dem gleichen Wert belegt sind.
  • Erbt eine Schnittstelle von mehreren Oberschnittstellen, so ist es zulässig, wenn die Oberschnittstellen jeweils ein gleichlautendes Attribut haben. So erbt etwa FlyingCarColors von CarColors und PlaneColors den Eintrag WHITE, BLACK und GREY.
  • Unterschnittstellen können aus zwei Oberschnittstellen die Attribute gleichen Namens übernehmen, auch wenn sie einen unterschiedlichen Wert haben. Das testet der Compiler nicht. FlyingCarColors bekommt aus CarColors ein WHITE mit 1 aber aus PlaneColors das Weiß mit 0. Daher ist auch der Zugriff FlyingCarColors.WHITE in dem Beispiel Colors auch nicht möglich und führt zu einem Compilerfehler. Bei der Benutzung muss ein unmissverständlicher qualifizierter Name verwendet werden, der deutlich macht, welches Attribut gemeint ist, also zum Beispiel CarColors.WHITE oder PlaneColors.WHITE. Ähnliches gilt für die Farbe GREY. Obwohl Grau durch die ursprüngliche Deklaration bei BaseColor und auch bei der Überschattung in PlaneColors immer Zwei ist, ist die Nutzung durch FlyingCarColors.GREY nicht zulässig. Das ist ein guter Schutz gegen Fehler, denn wenn der Compiler dies durchließe, könnte sich im Nachhinein die Belegung von GREY in BaseColors oder PlaneColors ohne Neuübersetzung aller Klassen ändern, und zu Schwierigkeiten führen. Diesen Fehler – die Oberschnittstellen haben für eine Konstante unterschiedliche Werte – müsste die Laufzeitumgebung erkennen. Doch das ist nicht möglich und in der Regel setzt der Compiler die Werte auch direkt in die Aufrufstelle ein und ein Zugriff auf die Konstantenwerte der Schnittstelle findet nicht mehr statt.

Ähnliche Beiträge

Veröffentlicht in Insel

Ein Gedanke zu “Inselupdate: Vererbung und Überschattung von statischen Variablen

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert