2015-10-18 123 views
5

在java網站教程page的示例中。兩個接口定義了相同的默認方法startEngine()。類FlyingCar實現了兩個接口,並且必須覆蓋startEngine(),因爲存在明顯的衝突。對此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); 
    } 
} 

我不明白爲什麼,從FlyingCarsuper被用來指的startEngine()兩個版本在OperateCarFlyCar接口。據我瞭解,startEngine()沒有在任何超級類定義,因此不應該被稱爲一個駐地。我還沒有看到super和兩個接口之間的任何關係,如FlyingCar

+4

'超級本身意味着超類。 'FlyCar.super'在Java 8中是新的,並且意味着在'FlyCar'界面中的實現。 – immibis

+1

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

+1

爲什麼不閱讀該教程而不是僅僅提取示例代碼? – Holger

回答

5

實現按我的理解,startEngine()沒有任何超類中定義的,因此不應該在一個被稱爲居民。

是的,它被定義。這是默認的實現,例如:

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

OperateCar.super.startEngine(key)將執行默認實現。

如果沒有默認的實現,只是一個接口方法, 那麼該語句將沒有任何意義,因爲接口不包含實現,像這樣:

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

我也沒有看到超級和在FlyingCar實施的兩個接口之間的任何關係

不知道我明白什麼你問。 super是一種調用父接口實現的方法。 沒有super,沒有其他表達方式。

+0

我知道有一個默認的實現,但是你的意思是它假設一個默認的類(超級),在這個默認的實現上做了什麼?這樣做是合乎邏輯的。如果有一個默認的超類,那麼現在我可以看到兩個接口和'super'之間的關係。 –

+2

@okeyxyz:沒有像「默認超類」這樣的事情,並不清楚你爲什麼這麼想。 'InterfaceName.super'是從實現類調用非抽象接口方法的語法。而已。它看起來像這樣*,因爲Java語言設計者這麼說*。這些非抽象接口方法被稱爲'default'方法,因爲它們需要將該關鍵字標記爲非抽象。這與以前的語言版本保持兼容,其中隱含「抽象」,即使未指定*和*也是如此,因爲Java語言設計師這樣說。 – Holger

5

如果您有一個實現多個接口的類,並且這些接口包含具有類似方法簽名的方法(例如,您的startEngine方法)。

爲了知道你指的是哪一種方法,你這樣做:

yourInterface.super.method(); 

你可以看看這個link這也解決了你的問題。

所以,你也可以這樣做:

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

或者這樣:

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

無論哪種方式,你必須指定你是從調用此方法的接口,如果你簡單地調用從界面的方法。

但是,這種特殊的情況是一個例子。更可能發生的事情是,你將會這樣做:

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

這也是有效的。但是,如果有兩個接口與具有相同的簽名,這也可能是一個情況下,你應該有一個聲明,方法的單親接口的方法,和兩個子接口,擴展它:

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:**請注意,***默認***修飾符僅在Java 8以上版本中可用。 – user3437460