-
接口定義
接口就是多個類的公共規範
接口是一種引用數據類型,最重要的內容就是其中的抽象方法
定義格式:
public interface MyInterfaceAbstract { // 這是一個抽象方法(public abstract 可省略) public abstract void methodAbs(); }
如果是java 7,那麼接口中可以包含:常量、抽象方法
如果是java 8,還可以包含:默認方法、靜態方法
如果是java 9,還可以額外包含:私有方法
-
使用接口
-
接口不能直接使用,必須有一個實現類來實現該接口
-
實現類必須覆蓋重寫接口中所有的抽象方法(去掉 abstract 關鍵字,加上方法體大括號)
如果實現類沒有覆蓋重寫接口中所有的抽象方法,那麼這個實現類必須是抽象類
-
創建實現類對象,進行調用操作
// 實現類 public class MyInterfaceAbstractImpl implements MyInterfaceAbstract{ @Override public void methodAbs(){ System.out.println("first method execute"); } public static void main(String[] args){ // 創建實現類對象,進行方法調用 MyInterfaceAbstractImpl impl = new MyInterfaceAbstractImpl(); impl.methodAbs(); // first method execute } }
-
-
默認方法定義(默認方法有方法體)
remarks:
- 接口當中的默認方法,可以解決接口升級的問題
- 可以通過實現類對象,直接調用
- 也可以在實現類中進行覆蓋重寫
// 接口 public interface MyInterfaceDefault { // 抽象方法 public abstract void methodAbs(); // 默認方法(public 可省略) public default void methodDefault(){ System.out.println("this is the newly added default method"); } } // 實現類A public class MyInterfaceDefaultA implements MyInterfaceDefault{ @Override public void methodAbs(){ System.out.println("abstract method execute"); } public static void main(String[] args){ MyInterfaceDefaultA defaultA = new MyInterfaceDefaultA(); // 調用靜態方法 defaultA.methodAbs(); // abstract method execute // 調用默認方法,如果實現類中沒有,就去找接口中的 defaultA.methodDefault(); // this is the newly added default method } } // 實現類B public class MyInterfaceDefaultB implements MyInterfaceDefault{ @Override public void methodAbs(){ System.out.println("abstract method execute"); } // 覆蓋重寫的默認方法 public void methodDefault(){ System.out.println("cover to rewrite"); } public static void main(String[] args){ MyInterfaceDefaultB defaultB = new MyInterfaceDefaultB(); defaultB.methodDefault(); // cover to rewrite } }
默認方法擴展:解決兩個默認方法之間重複代碼的問題,需要抽取一個共有方法
public interface MyInterfaceDefault{ // 默認方法1(public 可省略) public default void methodDefaultA(){ System.out.println("this is default method A"); methodCommon(); } // 默認方法2 public default void methodDefaultB(){ System.out.println("this is default method B"); methodCommon(); } // 共有方法,這個共有方法也是可以被實現類進行調用的 public default void methodCommon(){ System.out.println("this is common default method"); } } public class MyInterfaceDefaultImpl implements MyInterfaceDefault{ public void methodAnother(){ // 直接訪問到接口中的共有方法,這樣是不對的 methodCommon(); } }
-
靜態方法定義(從 java 8 開始,接口中允許定義靜態方法)
hint:就是將 abstract 或 default 換成 static 即可,和默認方法一樣,有方法體
Notice:應該通過接口名稱進行調用,不能通過實現類對象調用接口靜態方法
public interface MyInterfaceStatic{ // 定義靜態方法 public static void methodStatic(){ System.out.println("this is the static method"); } }
-
方法私有化(從 java 9 開始,接口中允許定義私有方法)
上述的 共有默認方法 或 共有靜態方法 是可以被實現類調用
但是共有方法不應該讓實現類使用,應該是私有化的,只有接口自己才能調用
私有方法定義
有兩種:普通私有方法 和 靜態私有方法
-
普通私有方法,解決多個默認方法之間的重複代碼問題
// 共有默認方法,用 private 關鍵字修飾 private void methodCommon(){ System.out.println("this is common default method"); }
-
靜態私有方法,解決多個靜態方法之間的重複代碼問題
// 共有靜態方法,用 private 關鍵字修飾 private static void methodCommon(){ System.out.println("this is common static method"); }
定義爲私有方法之後,就不能夠被實現類進行調用
-
-
常量定義
定義格式:
public static final 數據類型 常量名稱 = 數據值;
Notice:
- 必須進行賦值,一旦賦值不能改變
- 命名規則:使用完全的大寫字母,用下劃線進行分隔
// 定義 public interface MyInterfaceConst{ public static final int NUM_CLASS = 12; // 省略寫法 // int NUM_CLASS = 12; } // 調用 public class DemoConst{ public static void main(String[] args){ // MyInterfaceConst.NUM_CLASS = 20 // 錯誤寫法 System.out.println(MyInterfaceConst.NUM_CLASS); // 12 } }
-
final 關鍵字
final 表示最終的,不可改變的
常見的四種用法:
-
修飾一個類
// final 類不能被當做父類 public final class FinalClass{ public void method(){ } }
-
修飾一個方法
abstract 和 final 關鍵字不能重複使用(抽象方法必須要覆蓋重寫,但 final 關鍵字不能被覆蓋重寫)
public class Father{ // 這個方法是最終方法,也就是不能被覆蓋 重寫 public final void method(){ } }
-
修飾一個局部變量
對於基本類型:不可變 說的是變量中數據不可改變
對於引用類型:說的是變量中的地址值不可改變
public class Person { String name; public Person(String name){ this.name = name; } } public class DemoFinal { public static void main(String[] args) { // 使用 final 用來修飾局部變量,那麼這個變量就不能被改變 final int a = 10; System.out.println(a); // 10 // a = 20; // 不能修改 // 可以先定義,後賦值 final byte b; b = 20; final Person son = new Person("johny"); System.out.println(son); // demo_08_final_local_variable.Person@1b6d3586 System.out.println(son.name); // johny // son = new Person("johny"); 錯誤寫法 son.name = "anson"; System.out.println(son); // demo_08_final_local_variable.Person@1b6d3586 System.out.println(son.name); // anson } }
-
修飾一個 成員變量
和局部變量的使用方式是類似的,需要注意的是:
Notice:
- 成員變量有默認值,所以使用 final 之後必須手動賦值,或者通過構造方法賦值,二選一
-
-
接口的注意事項
-
接口是沒有靜態代碼塊 和 構造方法的
-
一個類的直接父類是唯一的(單繼承),但是一個類可以同時實現多個接口
public class MyinterfaceImpl implements MyInterfaceA, MyInterfaceB { ... }
如果實現類所實現的多個接口中,存在重複的抽象方法,那麼只需要覆蓋重寫一次
如果沒有實現接口中所有的抽象方法,那麼實現類就必須是一個抽象類
如果存在重複的默認方法,那麼實現類一定要對衝突的默認方法進行覆蓋重寫
如果一個類的直接父類的方法,和接口中的默認方法產生衝突,優先使用父類當中的方法(繼承優先於接口實現)
-
-
接口之間的多繼承
-
類與類之間是單繼承的,直接父類只有一個
-
類與接口之間是多實現的,一個類可以實現多個接口
-
接口與接口之間是多繼承的
多個父接口當中的抽象方法如果重複,沒有關係
多個父接口當中的默認方法重複,在子接口中需要覆蓋重寫
-
summary: