2015-10-18 36 views
5

In questo esempio sul tutorial del sito Web di java page. Due interfacce definiscono lo stesso metodo predefinito startEngine(). Una classe FlyingCar implementa entrambe le interfacce e deve eseguire l'override di startEngine() a causa del conflitto evidente.Confuso circa la parola chiave "super" in questo esempio Java

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); 
    } 
} 

Non capisco il motivo per cui, da FlyingCar, super viene utilizzato per fare riferimento a entrambe le versioni di startEngine() in OperateCar e FlyCar interfacce. A quanto ho capito, startEngine() non è stato definito in nessuna super classe, quindi non dovrebbe essere indicato come residente in uno. Anche io non vedo alcuna relazione tra super e le due interfacce come attuata in FlyingCar

+4

' super' da solo significa la superclasse. 'FlyCar.super' è nuovo in Java 8 e indica l'implementazione nell'interfaccia' FlyCar'. – immibis

+1

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

+1

Perché non leggi quel tutorial invece di estrarre semplicemente il codice di esempio? – Holger

risposta

5

Da quanto ho capito, startEngine() non è stato definito in qualsiasi classe super, quindi non dovrebbe essere denominato come residente in uno.

Sì, è stato definito. E 'l'implementazione di default, ad esempio:

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

OperateCar.super.startEngine(key) eseguirà l'implementazione di default.

Se non ci fosse implementazione di default, solo un metodo di interfaccia, allora l'istruzione avrebbe alcun senso, come l'interfaccia non conterrebbe un'implementazione, in questo modo:

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

Inoltre, non vedo alcuna relazione tra Super e le due interfacce implementate in FlyingCar

Non capisco cosa stai chiedendo super è un modo per chiamare l'implementazione nell'interfaccia genitore. Senza super, non c'è altro modo di esprimerlo.

+0

So che esiste un'implementazione predefinita, ma vuoi dire che presuppone una classe predefinita (super) su cui è stata implementata questa implementazione predefinita? Ha senso logico in questo modo. E se esiste una super classe predefinita, ora posso vedere la relazione tra le due interfacce e 'super'. –

+2

@okeyxyz: non esiste una "super classe predefinita" e non è chiaro il motivo per cui la pensi così. 'InterfaceName.super' è la sintassi per chiamare un metodo di interfaccia non astratto da una classe di implementazione. Questo è tutto. Sembra così * perché i progettisti del linguaggio Java lo hanno detto *. Questi metodi di interfaccia non astratti sono chiamati metodi 'default', perché hanno bisogno che tale parola chiave sia contrassegnata come non astratta. Questo per rimanere compatibile con le versioni linguistiche precedenti dove 'abstract' è implicito, anche se non specificato * e * perché lo hanno detto i progettisti del linguaggio Java. – Holger

5

Quando si dispone di una classe che implementa più interfacce e tali interfacce contengono metodi con la firma del metodo simile (ad esempio il metodo startEngine).

Per sapere quale metodo si fa riferimento, è fare:

yourInterface.super.method(); 

Si può dare un'occhiata a questo link che affronta anche la tua domanda.

Quindi, si potrebbe anche fare questo:

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

O questo:

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

In entrambi i casi, è necessario specificare l'interfaccia che si sta chiamando il metodo da, se si sta semplicemente chiamando il metodo dall'interfaccia.

Tuttavia, questa particolare situazione è un esempio per un motivo. Quello che sarà più probabile che accada è che si farà qualcosa del genere:

public int startEngine(EncryptedKey key) { 
    // Custom implemenation... 
} 

Che è anche valido. Tuttavia, se si dispone di due interfacce con un metodo che ha una firma identica, che potrebbe anche essere una situazione in cui si dovrebbe avere una singola interfaccia genitore che dichiara che il metodo, e due interfacce figlio che estenderlo:

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: ** Si noti che il modificatore *** *** *** è disponibile solo in Java 8 in poi. – user3437460

Problemi correlati