Java 8為介面(Interface)引進了一個新的特性,名為Default Method,講白一點其實就是可以在介面內寫一些已經實作的方法。也就是說,在Java 8介面不再只是開規格給類別實作而已,他現在還可以提供一些已經實作的方法給人使用。
如何宣告與使用?
Default Method的宣告方法很簡單,只要加上default關鍵字即可,需要注意的是,在介面內的方法必須宣告為public的。可以參考以下程式:
public interface MyInterfaceI {
default public void testDefaultMethod(int i) {
System.out.println("default method test2()");
if(i > 3) {
System.out.println(">3");
} else {
System.out.println("<=3");
}
}
}
要使用該Default Method時,只要透過實現該介面的類別,呼叫該Default Method即可,如下:
class MyInterfaceImpl implements MyInterfaceI {
}
public class MainClass {
public static void main(String[] args) {
MyInterfaceImpl impl = new MyInterfaceImpl();
impl.testDefaultMethod(2); // output: <=3
}
}
需要注意?
繼承介面時,若父介面有Default Method,則子介面會繼承他。如底下的範例:
public class InterfaceImpl implements InterfaceSon{ public static void main(String[] args) { InterfaceSon son = new InterfaceImpl(); son.test(); // output => InterfaceParent } } interface InterfaceParent { public default void test() { System.out.println("InterfaceParent"); } } interface InterfaceSon extends InterfaceParent{ }
Default Method是可以被覆寫(override)的,因此繼承之後你可以將之覆寫掉。如底下的範例,將繼承的介面Default Method覆寫掉,則程式在執行時就會跑覆寫的那個版本:
public class InterfaceImpl implements InterfaceSon{ public static void main(String[] args) { InterfaceSon son = new InterfaceImpl(); son.test(); // output => InterfaceSon } } interface InterfaceParent { public default void test() { System.out.println("InterfaceParent"); } } interface InterfaceSon extends InterfaceParent{ public default void test() { System.out.println("InterfaceSon"); } }
繼承之後,若不想要使用原本父類別的Default Method,則可宣告成抽象方法,讓實作類別實作該方法。可以參考底下範例:
public class InterfaceImpl implements InterfaceSon{ public static void main(String[] args) { InterfaceSon son = new InterfaceImpl(); son.test(); // output => InterfaceImpl } @Override public void test() { System.out.println("InterfaceImpl"); } } interface InterfaceParent { public default void test() { System.out.println("InterfaceParent"); } } interface InterfaceSon extends InterfaceParent{ public void test(); }
如果類別要實作的介面,剛好有兩個相同名稱,相同輸入參數的Default Method,則編譯器會出錯。可以參考底下程式:
public class InterfaceImpl implements Interface1, Interface2 { // 編譯器會報以下錯誤 // Duplicate default methods named test with the // parameters () and () are inherited from the types // Interface2 and Interface1 } interface Interface1 { public default void test() { System.out.println("Interface1"); } } interface Interface2 { public default void test() { System.out.println("Interface2"); } }
上面情況發生時,可以用覆寫來把Default Method蓋掉,在覆寫時還可以用super關鍵字來指定要用哪個實作的Default Method,可以參考底下程式:
public class InterfaceImpl implements Interface1, Interface2{ public void test() { Interface1.super.test(); // output => Interface1 } } interface Interface1 { public default void test() { System.out.println("Interface1"); } } interface Interface2 { public default void test() { System.out.println("Interface2"); } }
Default Method在使用時是沒有狀態的,所謂的狀態指的是在一般類別與抽象(abstract)類別裡,能在類別的欄位(field)存放資料,如存放布林值、整數、字串等等的資料,來代表此類別的狀態,而Default Method是存在於介面內的,介面是不允許存放資料欄位的,因此它唯一能操作的資料,只有透過參數傳進來的資料而已。
Static Methods
此外除了Default Method,現在在Java 8內,你也可以寫Static Method了,他的宣告方法就如同在一般類別內宣告static method一樣,如下:
public interface MyInterfaceI {
public static void invokeStaticMethod() {
System.out.println("It is static method!");
}
}
使用的話如下:
public class MainClass {
public static void main(String[] args) {
MyInterfaceI.invokeStaticMethod(); // output: It is static method!
}
}
沒有留言:
張貼留言