JAVA_面向對象_接口

  1. 接口定義

    接口就是多個類的公共規範

    接口是一種引用數據類型,最重要的內容就是其中的抽象方法

    定義格式:

    public interface MyInterfaceAbstract {
        // 這是一個抽象方法(public abstract 可省略)
        public abstract void methodAbs();
    }
    

    如果是java 7,那麼接口中可以包含:常量、抽象方法

    如果是java 8,還可以包含:默認方法、靜態方法

    如果是java 9,還可以額外包含:私有方法

  2. 使用接口
    1. 接口不能直接使用,必須有一個實現類來實現該接口

    2. 實現類必須覆蓋重寫接口中所有的抽象方法(去掉 abstract 關鍵字,加上方法體大括號)

      如果實現類沒有覆蓋重寫接口中所有的抽象方法,那麼這個實現類必須是抽象類

    3. 創建實現類對象,進行調用操作

    // 實現類
    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
        }
    }
    
  3. 默認方法定義(默認方法有方法體)

    remarks:

    1. 接口當中的默認方法,可以解決接口升級的問題
    2. 可以通過實現類對象,直接調用
    3. 也可以在實現類中進行覆蓋重寫
    // 接口
    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();
        }
    }
    
  4. 靜態方法定義(從 java 8 開始,接口中允許定義靜態方法)

    hint:就是將 abstract 或 default 換成 static 即可,和默認方法一樣,有方法體

    Notice:應該通過接口名稱進行調用,不能通過實現類對象調用接口靜態方法

    public interface MyInterfaceStatic{
        // 定義靜態方法
        public static void methodStatic(){
            System.out.println("this is the static method");
        }
    }
    
  5. 方法私有化(從 java 9 開始,接口中允許定義私有方法)

    上述的 共有默認方法 或 共有靜態方法 是可以被實現類調用

    但是共有方法不應該讓實現類使用,應該是私有化的,只有接口自己才能調用

    私有方法定義

    有兩種:普通私有方法 和 靜態私有方法

    1. 普通私有方法,解決多個默認方法之間的重複代碼問題

      // 共有默認方法,用 private 關鍵字修飾
      private void methodCommon(){
          System.out.println("this is common default method");
      }
      
    2. 靜態私有方法,解決多個靜態方法之間的重複代碼問題

      // 共有靜態方法,用 private 關鍵字修飾
      private static void methodCommon(){
          System.out.println("this is common static method");
      }
      

    定義爲私有方法之後,就不能夠被實現類進行調用

  6. 常量定義

    定義格式:public static final 數據類型 常量名稱 = 數據值;

    Notice:

    1. 必須進行賦值,一旦賦值不能改變
    2. 命名規則:使用完全的大寫字母,用下劃線進行分隔
    // 定義
    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
        }
    }
    
  7. final 關鍵字

    final 表示最終的,不可改變的

    常見的四種用法:

    1. 修飾一個類

      // final 類不能被當做父類
      public final class FinalClass{
          public void method(){
          }
      }
      
    2. 修飾一個方法

      abstract 和 final 關鍵字不能重複使用(抽象方法必須要覆蓋重寫,但 final 關鍵字不能被覆蓋重寫)

      public class Father{
          // 這個方法是最終方法,也就是不能被覆蓋 重寫
          public final void method(){
          }
      }
      
    3. 修飾一個局部變量

      對於基本類型:不可變 說的是變量中數據不可改變

      對於引用類型:說的是變量中的地址值不可改變

      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
          }
      }
      
    4. 修飾一個 成員變量

      和局部變量的使用方式是類似的,需要注意的是:

      Notice:

      1. 成員變量有默認值,所以使用 final 之後必須手動賦值,或者通過構造方法賦值,二選一
  8. 接口的注意事項
    1. 接口是沒有靜態代碼塊 和 構造方法的

    2. 一個類的直接父類是唯一的(單繼承),但是一個類可以同時實現多個接口

      public class MyinterfaceImpl implements MyInterfaceA, MyInterfaceB { ... }

      如果實現類所實現的多個接口中,存在重複的抽象方法,那麼只需要覆蓋重寫一次

      如果沒有實現接口中所有的抽象方法,那麼實現類就必須是一個抽象類

      如果存在重複的默認方法,那麼實現類一定要對衝突的默認方法進行覆蓋重寫

      如果一個類的直接父類的方法,和接口中的默認方法產生衝突,優先使用父類當中的方法(繼承優先於接口實現)

  9. 接口之間的多繼承
    1. 類與類之間是單繼承的,直接父類只有一個

    2. 類與接口之間是多實現的,一個類可以實現多個接口

    3. 接口與接口之間是多繼承的

      多個父接口當中的抽象方法如果重複,沒有關係

      多個父接口當中的默認方法重複,在子接口中需要覆蓋重寫

summary:在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章