Java-03 final、嵌套類、抽象類

Q:子類對象的內(nèi)存中,是否包含父類中定義的private成員變量?

A:依然包含 private只是降低了訪問權限,不影響內(nèi)存布局和內(nèi)存分布,外界無法訪問,但是子類對象內(nèi)存中依然包含。子類內(nèi)存中包含父類所有的成員變量,無論是否是私有的

final

  • 被final修飾的類不能被繼承
  • 被final修飾的方法不能被重寫
  • 被final修飾的變量,只能進行一次賦值
  • 其他跟在Swift/Flutter中相似

常量

Java中常量一般寫成 名稱一般大寫 static final修飾的稱之為常量(約定俗成的叫法,final修飾也可以叫做常量)

private static final int MY_AGE = 1;
  • 如果將基本類型或字符串定義為常量,并且在編譯時就能確定值,編譯器會使用常量值替換各處的常量名(類似于C語言的宏替換)

嵌套類

  • 嵌套類:定義在另一個類中的類
public class OuterClass {
  // 靜態(tài)嵌套類 
  static class StaticNestedClass {

  }
  // 非靜態(tài)嵌套類(內(nèi)部類)
  class InnerClass {

  }
}
  • 在嵌套類外層的類,稱為:外部類(Outer Class)
  • 最外層的外部類,稱為:頂級類(Top-level Class)

內(nèi)部類

內(nèi)部類:沒有被static修飾的嵌套類,非靜態(tài)嵌套類

  • 跟實例變量,實例方法一樣,內(nèi)部類跟外部類實例相關聯(lián),
  • 必須先創(chuàng)建外部類實例,然后通過外部類實例來創(chuàng)建內(nèi)部類實例
  • 內(nèi)部類不能定義除了編譯時常量以外的任何static成員
  • 內(nèi)部類可以直接訪問外部類的所有成員(即使被聲明為private)
  • 外部類可以直接訪問內(nèi)部類實例的成員變量、方法(即使被聲明為private)
  • 內(nèi)部類實例內(nèi)存中有指向外部類實例的指針

  OuterClass outer = new OuterClass();
  // 通過外部類實例創(chuàng)建內(nèi)部類實例
  InnerClass inner = outer.new InnerClass();

靜態(tài)嵌套類(Static Nested Class)

  • 靜態(tài)嵌套類: 被static修飾的嵌套類
  • 靜態(tài)嵌套類在行為上就是一個頂層類,只是定義的代碼寫在了另一個類中
  • 對比一般的頂級類,多了一些權限
    • 可以直接訪問外部類中除了實例變量、實例方法之外的其他成員(即使被聲明為private)
public class OuterClass {
  private static int count = 1;

  // 靜態(tài)嵌套類
  static class StaticNestedClass {
    public void run() {
      // 可以訪問頂層類的成員 即使是private
      OuterClass.count = 1;
      // 不需要類名也可以直接訪問外部類的成員
      System.out.println(count);
    }
  }
}

什么情況使用嵌套類?

  1. 如果類A只在類C中使用,可以考慮把A嵌套在C中

    • 封裝性更好
    • 程序包更加簡化
    • 增強可讀性,維護性
  2. 如果類A需要經(jīng)常訪問類C的非公開成員,可以考慮將A嵌套在C中

    • 也可以考慮將A隱藏起來,不對外暴露
  3. 如果需要經(jīng)常訪問非公共的實例成員,設計成內(nèi)部類(非靜態(tài)嵌套類),否則設計成靜態(tài)嵌套類 (能靜態(tài)盡量去靜態(tài))

局部類

  • 局部類:定義在代碼塊中的類(可以定義在方法中,for循環(huán)中,if語句中等代碼塊中)

  • 局部類不能定義除了編譯時常量以外的任何static成員

  • 局部類只能訪問final或者 有效final的局部變量

    • Java 8開始,如果局部變量沒有第二次賦值,就認為是有效final
  • 局部類可以直接訪問外部類的所有成員(即使被聲明為private)

  • 局部類只有被定義在實例相關的代碼塊中,才能直接訪問外部類中的實例成員

public class LocalClass {
  // 實例變量
  public int age = 10;

  // 靜態(tài)初始化塊 在類第一次初始化時調(diào)用
  static {
    class A {
      public void test() {
        // 跟實例相關的代碼塊中的局部類才能訪問實例成員
        // 會報錯
        // System.out.println(age);
      }
    }
    A a = new A();
    a.test();
  }

  // 初始化塊 在類的構造函數(shù)中調(diào)用
  {
    class A {
      public void test() {
        // 跟實例相關的代碼塊中的局部類才能訪問實例成員
        System.out.println(age);
      }
    }
    A a = new A();
    a.test();
  }

  public void run(){
    // count只賦值一次 被認為是有效fianl
    int count = 0;
    // 再次賦值的話就不被認為是有效final 局部類使用時會報錯
    // count = 10;
    // 局部類
    class A {
      // 報錯 不能定義除編譯時常量以外的static成員 
      // public static int age = 0;
      // 正確
      public static final int age = 10;
      
      public void test() {
        // 可以訪問final或者有效final的局部變量
        System.out.println(count);
      }
    }
  }
}

抽象類和抽象方法

  • 抽象方法 :被abstract修飾的方法

    • 只有方法聲明,沒有方法實現(xiàn)
    • 不能是private權限(因為定義抽象方法的目的就是讓子類去實現(xiàn))
    • 只能是實例方法,不能是類方法
    • 只能定義在抽象類、接口中
  • 抽象類:被abstract修飾的類
    • 可以定義抽象方法
    • 不能實例化,但可以自定義構造函數(shù)
    • 子類必須實現(xiàn)抽象父類中的所有抽象方法(除非子類也是一個抽象類)
    • 可以像非抽象類一樣定義成員變量,常量,嵌套類,初始化塊,非抽象方法等
    • 抽象類也可以完全不定義抽象方法
    • 也就是說,抽象類比非抽象類多了一些抽象方法,但是不能實例化了

跟flutter中的抽象類似

?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

友情鏈接更多精彩內(nèi)容