2015-10-18 6 views
5

In diesem Beispiel auf Java-Tutorial Tutorial page. Zwei Schnittstellen definieren die gleiche Standardmethode startEngine(). Eine Klasse FlyingCar implementiert beide Schnittstellen und muss wegen des offensichtlichen Konflikts startEngine() überschreiben.Verwirrt über "Super" -Schlüsselwort in diesem Java-Beispiel

public interface OperateCar { 
    // ... 
    default public int startEngine(EncryptedKey key) { 
     // Implementation 
    } 
} 
public interface FlyCar { 
    // ... 
    default public int startEngine(EncryptedKey key) { 
     // Implementation 
    } 
} 

public class FlyingCar implements OperateCar, FlyCar { 
    // ... 
    public int startEngine(EncryptedKey key) { 
     FlyCar.super.startEngine(key); 
     OperateCar.super.startEngine(key); 
    } 
} 

Ich verstehe nicht, warum, von FlyingCar, super verwendet wird, um beide Versionen von startEngine() in OperateCar und FlyCar Schnittstellen zu verweisen. Wie ich es verstehe, startEngine() wurde in keiner Super-Klasse definiert, sollte daher nicht als resident in einem bezeichnet werden. Ich sehe nicht, auch eine Beziehung zwischen super und den beiden Schnittstellen wie in realisiert FlyingCar

+4

' Super bedeutet für sich die Oberklasse. 'FlyCar.super' ist neu in Java 8 und bedeutet die Implementierung in der Oberfläche' FlyCar'. – immibis

+1

Siehe http://stackoverflow.com/questions/19976487/explicitely-calling-a-default-method-in-java – Eran

+1

Warum lesen Sie dieses Tutorial nicht nur den Beispielcode extrahieren? – Holger

Antwort

5

Wie ich es verstehe, startEngine() wurde nicht in jeder Superklasse definiert, daher nicht als Wohnsitz in einer genannt werden soll.

Ja, es wurde definiert. Es ist die Default-Implementierung, zum Beispiel:

public interface OperateCar { 
    // ... 
    default public int startEngine(EncryptedKey key) { 
     // Implementation 
    } 
} 

OperateCar.super.startEngine(key) wird die Standardimplementierung auszuführen.

Wenn es keine Default-Implementierung ist, nur eine Interface-Methode, dann wäre die Aussage nicht sinnvoll, da die Schnittstelle nicht eine Implementierung, wie diese enthalten würde:

public interface OperateCar { 
    // ... 
    int startEngine(EncryptedKey key); 
} 

Ich sehe auch keine Beziehung zwischen Super und den beiden Schnittstellen wie in FlyingCar

implementiert

Nicht sicher, ich verstehe was du fragst. super ist eine Möglichkeit, die Implementierung in der übergeordneten Schnittstelle aufzurufen. Ohne super gibt es einfach keine andere Möglichkeit, das auszudrücken.

+0

Ich weiß, dass es eine Standardimplementierung gibt, meinst du aber, dass sie eine Standardklasse (Super) annimmt, für die diese Standardimplementierung erstellt wurde? Es macht logisch Sinn so. Und wenn es eine Standard-Superklasse gibt, dann kann ich jetzt die Beziehung zwischen den beiden Schnittstellen und "super" sehen. –

+2

@okeyxyz: Es gibt keine solche Sache wie eine "Standard-Superklasse" und es ist nicht klar, warum du das denkst. 'InterfaceName.super' ist die Syntax zum Aufrufen einer nicht abstrakten Schnittstellenmethode aus einer Implementierungsklasse. Das ist es. Es sieht so aus *, weil die Java-Sprache-Designer so * sagten. Diese nicht abstrakten Schnittstellenmethoden werden als Standardmethoden bezeichnet, da sie das Schlüsselwort als nicht-abstrakt markieren müssen. Das ist kompatibel mit früheren Sprachversionen, in denen 'abstrakt' impliziert ist, auch wenn sie nicht spezifiziert sind * und *, weil die Java-Sprachdesigner dies sagten. – Holger

5

Wenn Sie eine Klasse implementieren, die mehrere Schnittstellen implementiert, und diese Schnittstellen Methoden mit ähnlicher Methodensignatur enthalten (z. B. Ihre startEngine-Methode).

Um welche Methode Sie sich beziehen, zu wissen, was Sie tun:

yourInterface.super.method(); 

Sie einen Blick auf diese link nehmen können, die auch Ihre Frage befasst.

So können Sie auch dies tun:

public class FlyingCar implements FlyCar, OperateCar{ 
    public int startEngine(EncryptedKey key) { 
     return FlyCar.super.startEngine(key); 
    } 
} 

Oder diese:

public class FlyingCar implements FlyCar, OperateCar{ 
    public int startEngine(EncryptedKey key) { 
     return Operate.super.startEngine(key); 
    } 
} 

In beiden Fällen müssen Sie die Schnittstelle geben Sie die Methode aufrufen, wenn Sie einfach anrufen die Methode von der Schnittstelle.

Allerdings ist diese besondere Situation ein Beispiel aus einem Grund. Was eher passieren wird ist, dass Sie etwas in der Art tun werden:

Das ist auch gültig. wenn Sie zwei Schnittstellen mit einem Verfahren haben jedoch die eine identische Signatur hat, die auch eine Situation sein könnte, in dem Sie eine alleinerziehende Mutter Schnittstelle haben sollte, der diese Methode deklariert, und zwei untergeordnete Schnittstellen erweitern es:

public interface Car { 
    // ... 
    default public int startEngine(EncryptedKey key) { 
     // Default implementation 
}; 
} 

public interface FlyCar extends Car { 
    // Methods unique to FlyCar 
} 

public interface OperateCar extends Car { 
    // methods unique to OperateCar 
} 
+4

** Reamrks: ** Beachten Sie, dass der Modifikator *** default *** erst ab Java 8 verfügbar ist. – user3437460