Java8新特性-接口中的静态方法与默认方法
今天上午在讀《Effective Java》時,有這樣一句話:”接口中“不能有靜態方法,于是聯想起面試時老是被問接口相關的東西,決定總結一下,誰知道這一總結,就發現了自己知識的一大漏洞。
? 在以前的思維中,接口中所有的方法都是抽象的,而抽象的方法沒有static,有static的方法不能被override。但是在java8以后,允許在接口里定義默認方法和類方法。
一、接口代碼
TestInterfac:
? ? public interface TestInterface {
? ??
//此處的靜態方法只能被public修飾(或者省略不寫),不能是private或者protected。
? ? ? static void out1() {
? ? ??
? ? ? ? System.out.println("接口的靜態輸出方法1");
? ? ??
? ? ? }
? ? ??
? ? ? void out2();?? ?
? ? ??
? ? ? default void out3() {
? ? ?? ?
? ? ?? ??? System.out.println("默認輸出方法3");
? ? ??
? ? ??}
? ? ?
? ? }
實現類 TestImpl:
public class TestImpl implements TestInterface{
?? ?public static void main(String[] args) {
?? ???
?TestInterface.out1();
?? ???TestImpl demo = new TestImpl();
?? ???demo.out2();
? demo.out3();
?? ?}
? ? ?
?? ?@Override
?? ?public void out2() {
?? ???
?System.out.println("實現普通輸出方法2");
?? ?
}
?? ?
}
運行結果:
? ? ? ???
? ? ? 當我們在實現接口時,發現默認只需要實現out2方法,因為只有out2方法是抽象的。當然也可以手工實現將out3()方法重寫,但是不能夠重寫靜態方法out1。可以用TestInterface.out1()直接調用接口中的靜態方法。
? ? ? 當創建demo對象時,可以直接調用out2,out3,但不可以調用靜態方法out1()。為什么不能調用out1()?因為一個類可以實現多個接口。如果2個接口具有相同的 static 方法,則它們都將被繼承,編譯器將不知道要調用哪個。
? ? ? Java8為什么要引入默認方法?
? ? ? 默認方法的主要優勢是提供一種拓展接口的方法,而不破壞現有代碼。加入我們有一個已經投入使用接口需要拓展一個新的方法,在JDK8以前,如果為一個使用的接口增加一個新方法,則我們必須在所有實現類中添加該方法的實現,否則編譯會出現異常。如果實現類數量少并且我們有權限修改,可能會工作量相對較少。如果實現類比較多或者我們沒有權限修改實現類源代碼,這樣可能就比較麻煩。而默認方法則解決了這個問題,它提供了一個實現,當沒有顯示提供其他實現時就采用這個實現。這樣新添加的方法將不會破壞現有代碼。
? ? ? 默認方法的另一個優勢是該方法是可選的,子類可以根據不同的需求Override默認實現。
二、繼承的父類和實現的接口中有相同的方法
父類TestClass:
?public class TestClass {
? ? public void out3() {
?? ???
?System.out.println("我是父類中的輸出方法3");
?? ?
}
}
子類:
public class TestImpl extends TestClass implements TestInterface{
?? ?public static void main(String[] args) {
?? ???
TestInterface.out1();
?? ??? ?TestImpl demo = new TestImpl();
?? ??? ?demo.out2();
?? ??? ?demo.out3();
?? ?
}
? ? ?
?? ?@Override
?? ?public void out2() {
?? ?
?? ?System.out.println("實現普通輸出方法2");
?? ?
}
?? ?
}
運行結果:
??
?
所以,當繼承的父類和實現的接口中有相同簽名的方法時,優先使用父類的方法。
三、實現的多個接口中有相同的方法。
接口1:
public interface TestInterface {
? ?? ?default void out3() {
?? ??? ?
System.out.println("默認輸出方法3");
? ?? ?
}
?
}
接口2:
interface TestInterface2 {
?? ? default void out3() {
?? ???
? ?System.out.println("第二個接口中的默認輸出方法3");
?? ? ?
}
}
實現類:
public class TestImpl implements TestInterface,TestInterface2{
?? ?public static void main(String[] args) {
?? ???
TestImpl demo = new TestImpl();
?? ??? ?demo.out3();
?? ?}
? ? ?
}
當我們去寫實現類的時候發現會報錯,錯因如下:
?
必須在實現類中通過重寫方法解決沖突問題,否者無法通過編譯,在重寫的方法中可以通過 接口名.super.方法名(); 的方式顯示調用需要的方法。
為什么java的接口里的屬性必須是static的?并且要求必須是final的呢?
接口中的數據對所有實現類只有一份,所以是static
要使實現類為了向上轉型成功,所以必須是final的(接口不能被實例化,所以接口里面如果是變量的話不會被賦初始值這樣就會出問題,所以必須是final的。其實還是為了安全考慮的) 這樣接口也能起到一定的模版的作用。
---------------------?
轉載于:https://www.cnblogs.com/ly570/p/10942272.html
總結
以上是生活随笔為你收集整理的Java8新特性-接口中的静态方法与默认方法的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 简单电商购物过程(续1)
- 下一篇: 我爱Java系列---【登录案例】