Advanced   Java   Services Statische Methoden in Interfaces


Statische Methoden in Interfaces

Seit Java 8 sind statische auscodierte und auch nichtstatische auscodierte Methoden in Interfaces erlaubt, letzere bekommen das Schlüsselwort default vor dem Returntyp vorangestellt. Da sich die Methoden in einem Interface befinden sind sie automatisch public. Viele alte Interfaces sind mit neuen statischen und default-Methoden ausgestattet worden. Hier ein Blick auf das in Java 1.2 eingeführte Interface Comparator.

Wie man sieht gibt es seit Java 8 nun 9 statische und 5 default Methoden in Comparator. Beispiele, wie wir diese verwenden können folgen später.


Einfache Eigenschaften

Statische Methoden in einem Interface verhalten sich etwas anders als solche in einer Klasse. Wir betrachten deshalb ein Interface mit einer statischen Methode und zwei implementierende Klassen. Beide Klassen implementieren das Interface, die zweite Klasse "überschreibt" jedoch die statische Methode aus dem Interface.

interface StaticTest
{
   static void staticMethod()
   {
      System.out.println("StaticTest.staticMethod() called");
   }
}

class StaticTestImpl1 implements StaticTest
{
}

class StaticTestImpl2 implements StaticTest
{
   static void staticMethod()
   {
      System.out.println("staticMethod in StaticTestImpl");
   }
}


public class StaticMethods
{
   public static void main(String[] args)
   {
      // Aufruf der statischen Methode
      StaticTest.staticMethod();
      //Ausgabe: StaticTest.staticMethod() called

      //StaticTestImpl1.staticMethod();
      // Fehler: staticMethod() is undefined for the type StaticTestImpl1

      StaticTestImpl2.staticMethod();
      //StaticTest2.staticMethod();
      StaticTestImpl1 sti = new StaticTestImpl1();
   }
}

Man prüft leicht die folgenden Regeln nach


Zugriff auf statische Daten

Wir erweitern unser Beispiel um einen statischen Datenteil.

interface StaticTest
{
   int staticData = 17;
   static void staticMethod()
   {
      System.out.println("staticMethod in StaticTest: " + staticData);
   }
}

class StaticTestImpl1 implements StaticTest
{
}

class StaticTestImpl2 implements StaticTest
{
   static int staticData = 42;

   //@Override  // The method staticMethod() of type StaticTestImpl2 must override or implement a supertype method
   // kein Override für statische Methoden
   public static void staticMethod()
   {
      System.out.println("staticMethod in StaticTest: " + staticData);
   }
}

class StaticTestImpl3 extends StaticTestImpl2
{
   static int staticData = 69;
   // kein Überschreiben
}

und rufen die Methode sowohl zum Interface als auch zu den Klassen StaticTestImpl2 und StaticTestImpl3

public class StaticMethodsInInterfaces
{
   public static void main(String[] args)
   {
      // Aufruf der statischen Methode über das Interface  OK
      StaticTest.staticMethod();  // 17

      //StaticTestImpl1.staticMethod();
      //staticMethod() is undefined for the type StaticTestImpl1

      StaticTestImpl2.staticMethod();  // 42

      StaticTestImpl3.staticMethod(); // 42 !
   }
}

Wir können zwar die statische Methode zum Namen der Kindklasse rufen, die Methode verwendet aber die Daten aus der Klasse in der sie definiert ist.
Es gilt also die Regel: