一篇文章幫你快速搞懂Java內部類

問題描述

Java內部類有什麼好處?爲什麼需要內部類?

解答

首先舉一個簡單的例子,如果你想實現一個接口,但是這個接口中的一個方法和你構想的這個類中的一個方法的名稱,參數相同,你應該怎麼辦?

這時候,你可以建一個內部類實現這個接口。由於內部類對外部類的所有內容都是可訪問的,所以這樣做可以完成所有你直接實現這個接口的功能。

不過你可能要質疑,更改一下方法的不就行了嗎?

的確,以此作爲設計內部類的理由,實在沒有說服力。
真正的原因是這樣的,Java中的內部類和接口加在一起,可以解決一個問題,此問題經常被C++程序員抱怨,那就是Java中沒有多繼承。

實際上,C++的多繼承設計起來很複雜,而Java通過內部類加上接口,可以很好的實現多繼承的效果。

一、常規內部類

  1. 常規內部類沒有用static修飾且定義在在外部類類體中。
  2. 常規內部類中的方法可以直接使用外部類的實例變量和實例方法。
  3. 在常規內部類中可以直接用內部類創建對象

具體代碼如下:

public class MyOuter {
    private int x = 100;
 // 創建內部類
  class MyInner {
     private String y = "Hello!";
     public void innerMethod() {
        System.out.println("內部類中 String =" + y);
        System.out.println("外部類中的x =" + x);// 直接訪問外部類中的實例變量x
         outerMethod();
        System.out.println("x is" + MyOuter.this.x);
     }
   }
   public void outerMethod() {
  x++;
 }
 public void makeInner() {
//在外部類方法中創建內部類實例
  MyInner in = new MyInner();
 }
 /**
  * @param args
  */
 public static void main(String[] args) {
  MyOuter mo = new MyOuter();
  // 使用外部類構造方法創建mo對象
  MyOuter.MyInner inner = mo.new MyInner();//常規內部類需要通過外部類的實例才能創建對象,與實例變量需要通過對象來訪問相似
  // 創建inner對象
  inner.innerMethod();
  // TODO Auto-generated method stub
 }
}

運行結果:

內部類中 String =Hello!
外部類中的x =100
x is101

二、靜態內部類

  1. 與類的其它成員相似,可以用static修飾內部類,這樣的類稱爲靜態內部類。靜態內部類與靜態內部方法相似,只能訪問外部類的static成員,不能直接訪問外部類的實例變量與實例方法,只有通過對象引用才能訪問。

  2. 由於static內部類不具有任何對外部類實例的引用,因此static內部類中不能使用this關鍵字來訪問外部類中的實例成員,但是可以訪問外部類中的static成員。這與一般類的static方法相同。

具體代碼:

package com.m.ou;
public class MyOuter {
  public static int x=100;
  public static class MyInner{
    private String y="Hello!";
    public void innerMethod(){
    System.out.println("x="+x);
    System.out.println("y="+y);  
  }
  
  
 }
 /**
  * @param args
  */
 public static void main(String[] args) {
  MyOuter.MyInner si=new MyOuter.MyInner();//靜態內部類不通過外部實例就可以創建對象;與類變量可以通過類名訪問相似
  si.innerMethod();
  // TODO Auto-generated method stub
 }
}

運行結果:

  x=100
  y=Hello!

三、局部內部類

在方法體或語句塊(包括方法、構造方法、局部塊或靜態初始化塊)內部定義的類成爲局部內部類。局部內部類不能加任何訪問修飾符,因爲它只對局部塊有效。

  1. 局部內部類只在方法體中有效,就想定義的局部變量一樣,在定義的方法體外不能創建局部內部類的對象
  2. 在方法內部定義類時,應注意以下問題:
  • 方法定義局部內部類同方法定義局部變量一樣,不能使用private、protected、public等訪問修飾說明符修飾,也不能使用static修飾,但可以使用final和abstract修飾。
  • 方法中的內部類可以訪問外部類成員。對於方法的參數和局部變量,必須有final修飾纔可以訪問。
  • static方法中定義的內部類可以訪問外部類定義的static成員。
    示例代碼:
public class Jubu {
 private int size=5,y=7;
 public Object makeInner(int localVar){
  final int finalLocalVar=localVar;
  //創建內部類,該類只在makeInner()方法有效,就像局部變量一樣。在方法體外部不能創建MyInner類的對象
  class MyInner{
   int y=4;
   public String toString(){
    return "OuterSize:"+size+
        "\nfinalLocalVar"+" "+"this.y="+this.y;
   }   
  }
   
  return new MyInner();  
}
}
class Main{ /**
  * @param args
  */
 public static void main(String[] args) {
  
  Object obj=new Jubu().makeInner(47);//創建Jubu對象obj,並調用它的makeInner()方法,該方法返回一個
  //該方法返回一個MyInner類型的的對象obj,然後調用其同toString方法。
  System.out.println(obj.toString());
  // TODO Auto-generated method stub
 }

}  

運行結果:

OuterSize:5
finalLocalVar this.y=4

四、匿名內部類

定義類的最終目的是創建一個類的實例,但是如果某個類的實例只是用一次,則可以將類的定義與類的創建,放到與一起完成,或者說在定義類的同時就創建一個類。以這種方法定義的沒有名字的類稱爲匿名內部類

聲明和構造匿名內部類的一般格式如下:

 new ClassOrInterfaceName(){
    /*類體*/ }
  1. 匿名內部類可以繼承一個類或實現一個接口,這裏的ClassOrInterfaceName是匿名內部類所繼承的類名或實現的接口名。但匿名內部類不能同時實現一個接口和繼承一個類,也不能實現多個接口。如果實現了一個接口,該類是Object類的直接子類,匿名類繼承一個類或實現一個接口,不需要extends和implements關鍵字。
  2. 由於匿名內部類沒有名稱,所以類體中不能定義構造方法,由於不知道類名也不能使用關鍵字來創建該類的實例。實際上匿名內部類的定義、構造、和第一次使用都發生在同樣一個地方。此外,上式是一個表達式,返回的是一個對象的引用,所以可以直接使用或將其複製給一個對象變量。例:
TypeName obj=new Name(){
   /*此處爲類體*/
      }

同樣,也可以將構造的對象作爲調用的參數。例:

  someMethod(new Name(){
   /*此處爲類體*/  });

示例代碼:

public class NiMing {
 private int size=5;
 public Object makeInner(int localVar){
  final int finalLocalVar=localVar;
  return new Object(){
   //使用匿名內部類
   public String toString(){
    return "OuterSize="+size+"\nfinalLocalVar="+finalLocalVar;
   }      
  };
 }
 /**
  * @param args
  */
public static void main(String args[])
 {
 Object obj=new NiMing().makeInner(47);
 System.out.println(obj.toString()); 
 }
}

運行結果

   OuterSize=5
   finalLocalVar=47

更多內容,敬請關注公衆號【魯班AD】
在這裏插入圖片描述

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