java基礎語法7--類的高級概念/訪問修飾符/封裝/內部類/初始化塊

訪問修飾符

概念:用來定義屬性的行爲,用於在特定的情況下可以訪問

類的每一個成員(包括成員變量、方法和構造器)都有一個訪問修飾符,用來判斷誰可以訪問該成員。訪問修飾符允許我們在設計程序的時候,就考慮到誰可以訪問一個對象的不同屬性和行爲。

Java爲類中的成員提供了四種訪問級別,按照訪問權限由大到小排列如下:

  • 公開訪問級別:使用public關鍵字修飾。用public關鍵字修飾的成員對外公開,即公開成員可以被任何其它對象訪問。
  • 受保護訪問級別:使用protected關鍵字修飾。受保護的成員可以被同一包中的類所訪問,還可以被類的子類所訪問,不管子類是在哪個包中。
  • 默認訪問級別:沒有訪問修飾符。默認訪問級別的成員可以被同一包中的其它類所訪問。
  • 私有訪問級別:使用private關鍵字修飾。它是四種訪問修飾符中級別最低的。私有成員只有類本身可以訪問,不對外公開。
  • 注:受保護和默認訪問是相似的,因爲二者都授予可以訪問同一包中的其它類。受保護訪問實際上比默認訪問的限制更小,因爲受保護訪問也授予訪問在包外的子類。
  • 注:

            

訪問級別:private-->default-->protected-->public

 

封裝

封裝是使類中的成員變量都是private,並提供public方法訪問這些成員變量的技術。如果一個成員變量被聲明爲private,那麼它就不能被其它類訪問,從而隱藏了類中的成員變量。因此,封裝也被稱爲數據隱藏。

  • 注:繼承、封裝、多態、抽象是面向對象的四大基本概念

封裝有很多好處,包括:

  • 類的成員變量可以成爲只讀或者只寫的。例如,SalesPerson類中的成員變量id是隻讀的,在SalesPerson對象實例化後,id成員變量就無法改變了。
  • 類可以對存儲在其成員變量中的內容有一個整體的控制。例如,SalesPerson類中的成員變量commissionRate的值只能在0.0和 0.20之間。
  • 類的用戶不需要知道類是如何存儲數據的。類可以改變一個成員變量的數據類型,而類的用戶不需要改變其代碼。

理解靜態成員

關鍵字static允許成員變量或方法不與類的特定實例關聯。通過關鍵字static聲明的成員變量或方法可以被認爲是全局的,任何其它類可以直接訪問靜態成員變量或調用靜態方法,而不需要該類的一個實例。

類的靜態成員經常被稱爲類成員,因爲靜態成員與類相關,而不是類的某個實例。非靜態的成員變量和方法經常被稱爲實例成員,因爲非靜態的成員變量和方法只存在於類的實例中。

類的非靜態成員變量和方法在類沒有實例化之前是不存在的。但是,靜態成員是與類相關聯的。JVM在加載類到內存後,就給靜態成員變量和方法分配了內存。也就是說,類一旦加載後,我們就可以馬上使用靜態成員變量和方法了。

訪問靜態變量和方法

靜態成員變量和方法不能使用引用來訪問,因爲引用是指類的實例,而我們不需要類的實例來訪問靜態成員。訪問靜態成員要使用類名。

例如:

public class persion{

public static String username = 張三;

 

Public static void printf()

{

System.out.println(你好嗎);

}

]

調用username是不需要new persion()再來調用,直接用類名調用persion.username調用,同樣的,調用printf方法也是persion.printf()。

 

我們已經使用了靜態成員變量和靜態方法。如果我們看到一個成員變量或方法是通過類名來訪問的,那麼我們就可以說該成員變量或者方法是靜態的。例如,在本書中我們已經用過很多次System.out。

靜態方法不能訪問實例成員(不能訪問非靜態成員)

 

  1. 靜態方法只能訪問靜態成員,不能訪問非靜態成員,非靜態成員函數可以訪問靜態成員

 

靜態初始化塊

除了聲明靜態成員變量和方法外,關鍵字static還有另外一種用法。Java類可以包含一個靜態初始化塊,靜態初始化塊是一組當類被JVM的類加載器加載時執行的語句。

類被類加載器加載一次,靜態初始化塊的作用是允許類執行任何所需的只需要發生一次的設置任務。

靜態初始化塊通過如下的語法形式定義:

 

static {

//語句出現在這裏。

}

 

  • 類的靜態初始化塊只被運行一次。
  • 靜態初始化塊在構造器執行之前加載

 

實例初始化塊

用法:

{

//內容

}

實例初始化塊與靜態初始化塊類似,它在類的對象每次實例化時執行一次。實例初始化塊和構造器二者之間的不同之處在於實例初始化塊在構造器調用之前執行。

實例初始化塊的語法形式很簡單,只需要在類中用大括號括起代碼塊即可。注意,實例初始化塊不使用任何關鍵字,也沒有名稱。

  1. 實例初始化放在屬性之下,構造之上

 

實例初始化塊中的語句在任何父類構造器調用之後,在子類構造器調用之前執行。當對象被實例化,並且類包含有實例初始化塊時,下面的事件按順序發生:

  • 子類中相應的構造器被調用。
  • 執行對super的調用,控制流程跳轉到相應的父類構造器。
  • 父類構造器執行完,控制流程跳轉回子類構造器。
  • 在該子類構造器中的super()後面的任何語句執行前,實例初始化塊執行。
  • 最後,執行子類構造器中super()後面的語句。

 

  1. 實例初始化快在每次新建對象時都調用

 

在生成對象的時候,執行順序是:

1、父類靜態初始化快

2、子類靜態初始化塊

3、父類實例初始化塊

4、父類構造函數中的代碼

5、子類實例化初始化塊

6、子類構造函數中的代碼(super()後面的代碼塊)

 

  1. 現在已經不怎麼用實例初始化塊,用有參構造代替了代碼塊,相當於整合了無參構造和代碼塊

 

New出一個對象在調用構造函數做的事:

  1. 在堆中生成一個對象,爲其分配空間
  2. 爲成員變量分配存儲空間
  3. 爲成員變量賦初值
  4. 執行構造函數中的代碼
  • 實例初始化塊在3-4之間執行

 

內部類

在類內部除了可以定義成員變量與方法。在Java中,還可以在類的內部定義類。這種在類的內部定義的類,稱爲內部類。內部類所在的類稱爲外部類。

Java中的內部類可以分爲四種,分別是:靜態內部類、成員內部類、局部內部類、匿名內部類。

內部類

類型

說明

靜態內部類

作爲類的靜態成員,存在於某個類的內部

成員內部類

作爲類的成員,存在於某個類的內部

局部內部類

存在於某個方法內部的類

匿名內部類

存在於某個類的內部,但是無類名的類

 

靜態內部類

靜態內部類的定義方法如下:

 

class Outer {

  static int f(){

  }

  static class Inner {

      public void g(){

        f();

   }

  }

}

注意:靜態內部類調用外部類的方法只能調用靜態的。

這裏,Inner類存在於Outer類的內部,作爲Outer的靜態成員。由於靜態成員可以在不創建類的情況下被使用,因此,我們可以不創建Outer類的對象,而直接引用Inner類。

同java文件中其他類調用這個靜態內部類方式:

 

Inner ob = new Inner();   //直接調用靜態內部類

ob.g();

 

 

如果要在其他java文件中調用這個靜態內部類,就寫成:

 

Inner ob = new Outer.Inner();   //直接調用靜態內部類

ob.g();

  1. 分析結論:靜態內部類雖然是外部類的成員,但是在未創建外部類的對象的情況下,可以直接創建靜態內部類的對象。此外,靜態內部類可以引用外部類的靜態成員變量和靜態方法,但是不能引用外部類的普通成員。例如,如果在靜態內部類中引用外部類的普通成員,就會出現編譯錯誤。

成員內部類

成員內部類的定義方法如下:

 

class Outer {

  private int i;

  Private int t;

  class Inner {

        public int i;

        Public int j;

        Public void g(){

        this.i = Outer.this.i;

        j = t;

}

  }

}

注意:在內部類的方法中調用外部類成員變量的時候,如果調用的變量名和本內部類的變量名不存在二義性,可以直接調用外部成員變量,如果名字存在二義性,那麼就要寫成(外部類名.this.成員名),方法的調用是一樣的。調用內部類的成員那麼可以直接用(this.成員名)調用。

這裏,Inner類存在於Outer類的內部,作爲Outer的成員。與靜態內部類不同的是,Inner類定義時沒有static修飾符,同時,只有創建了Outer類的實例對象後,才能使用Inner類的對象。

調用方式:

 

InnerDemo out = new InnerDemo ();     //實例化一個InnerDemo類的對象

Inner in = out.new Inner();    //Inner類的對象通過外部類的對象創建

in.g();

 

  1. 分析結論:成員內部類可以調用外部類的所有成員。但是隻有創建了外部類的對象後,才能引用外部的成員。

 

局部內部類

局部內部類是在類的方法內部定義的類。局部內部類只能在方法內部中使用。一旦方法執行完畢,局部內部類就會從內存中被清除。

代碼清單演示了局部內部類的使用。

  1.  
  2.  
  3.  
  4.  
  5.  
  6.  
  7.  
  8.  
  9.  
  10.  
  11.  
  12.  
  13.  
  14.  
  15.  
  16.  
  17.  
  18.  
  19.  
  20.  
  21.  
  22.  
  23.  

/*代碼清單 LocalDemo.java

  演示局部內部類的使用

*/

 

public class LocalDemo {

  int a = 10;

  void f() {

    class Inner {

  int b = 20;

  void g() {

    System.out.println(a);

System.out.println(b);

  }

}

Inner in = new Inner();

in.g();

  }

  

  public static void main(String[] args) {

    LocalDemo local = new LocalDemo();

local.f();

  }   

}

在LocalDemo程序中,方法f()內定義了一個局部內部類Inner,這個內部類只能在f()方法內使用。在第15行,我們實例化了內部類Inner,然後在第16行執行局部內部類的方法g()。

必須注意的是,如果局部內部類中要使用它所在的方法中的局部變量,那麼就需要將這個局部變量定義爲final的。

 

匿名內部類

匿名內部類是一種特殊的內部類,這種類沒有名字。匿名內部類的定義與對象的創建合併在一起,整個動作看起來像產生對象似的。匿名內部類是爲唯一對象而定義的類。當我們只需要創建一個類的對象,而且用不上它的名字時,使用內部類可以使代碼看上去簡潔清楚。

匿名內部類一般通過如下形式定義,並且在定義類的同時進行對象實例化:

 

new 類或者接口的名字() {

  //匿名內部類的主體

}

new後面是一個類或者接口,然後是一個大括號。在大括號中是匿名內部類的主體,這個主體就是類或者接口的實現。如果是類,那麼匿名內部類是該類的子類。如果是接口,匿名內部類需要完成對接口的實現。一般用與對類裏面的方法進行重寫。

總結

本章內容總結如下:

  • Java爲類中的成員提供了四種訪問級別,按照訪問權限由大到小排列,分別是:公有的(public)、受保護的(protected)、私有的(private)和默認的(無訪問修飾符)。
  • 通過用private訪問修飾符隱藏類中的成員變量,稱爲封裝。
  • 靜態成員變量或靜態方法並不與類的每個實例關聯。靜態成員變量或者靜態方法只有單個實例,它們對類的所有實例以及程序中的其它類是共享的。
  • 靜態初始化塊在類裝載時執行。實例初始化塊在類被實例化時執行,在構造器調用之間調用。
  • 內部類是在類的內部定義的類。在Java中,內部類有四種形式,分別是靜態內部類、成員內部類、局部內部類、匿名內部類。

 

java文件與類文件的關係

1、java文件中,包含幾個類,就對應的產生幾個相應的類文件

2、java文件的名稱,不一定和類文件的名稱保持一樣

     .1)兄弟類類文件的命名規則就是“兄弟類.class”

     .2)成員內部類類文件的命名規則就是“外部類$內部類.class”

     .3)局部內部類類文件的命名規則就是“外部類$內部類出現的次數 + 內部類.class”

3、一個java文件中,只允許出現一個public修飾的外部類,其他的而外部類都是default

 

 

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