1. 程式人生 > >java四種內部類詳解

java四種內部類詳解

一般來說,有4中內部類:常規內部類、靜態內部類、區域性內部類、匿名內部類。

 一.常規內部類:常規內部類沒有用static修飾且定義在在外部類類體中。
  1.常規內部類中的方法可以直接使用外部類的例項變數和例項方法。
  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

 }

}
  4.執行結果:
  
                                內部類中 String =Hello!
    外部類中的x =100
    x is101

 二.靜態內部類:與類的其他成員相似,可以用static修飾內部類,這樣的類稱為靜態內部類。靜態內部類與靜態內部方法相似,只能訪問外部類的static成員,不能直接訪問外部類的例項變數,與例項方法,只有通過物件引用才能訪問。
  3.由於static內部類不具有任何對外部類例項的引用,因此static內部類中不能使用this關鍵字來訪問外部類中的例項成員,但是可以訪問外部類中的static成員。這與一般類的static方法想通
  4.例項程式碼:
 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

 }

}
  4.執行結果:
  x=100
  y=Hello!
 三.區域性內部類:在方法體或語句塊(包括方法、構造方法、區域性塊或靜態初始化塊)內部定義的類成為區域性內部類。
  區域性內部類不能加任何訪問修飾符,因為它只對區域性塊有效。
  1.區域性內部類只在方法體中有效,就想定義的區域性變數一樣,在定義的方法體外不能建立區域性內部類的物件
  2.在方法內部定義類時,應注意以下問題:
   1.方法定義區域性內部類同方法定義區域性變數一樣,不能使用private、protected、public等訪問修飾說明符修飾,也不能使用static修飾,但可以使用final和   abstract修飾
   2.方法中的內部類可以訪問外部類成員。對於方法的引數和區域性變數,必須有final修飾才可以訪問。
   3.static方法中定義的內部類可以訪問外部類定義的static成員
  3.程式程式碼:
 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

 }


}  
  4.執行結果:
  
  OuterSize:5
  finalLocalVar this.y=4
 四.匿名內部類:定義類的最終目的是建立一個類的例項,但是如果某個類的例項只是用一次,則可以將類的定義與類的建立,放到與一起完成,或者說在定義類的同時就建立一個類
  以這種方法定義的沒有名字的類成為匿名內部類。
   宣告和構造匿名內部類的一般格式如下:
   new ClassOrInterfaceName(){

    /*類體*/ }

   1.匿名內部類可以繼承一個類或實現一個介面,這裡的ClassOrInterfaceName是匿名內部類所繼承的類名或實現的介面名。但匿名內部類不能同時實現一個介面和繼承一個類,也不能實現多個介面。如果實現了一個介面,該類是Object類的直接子類,匿名類繼承一個類或實現一個介面,不需要extends和implements關鍵字。
  
   2.由於匿名內部類沒有名稱,所以類體中不能定義構造方法,由於不知道類名也不能使用關鍵字來建立該類的例項。實際上匿名內部類的定義、構造、和第一次使用都發生在同樣一個地方。此外,上式是一個表示式,返回的是一個物件的引用,所以可以直接使用或將其複製給一個物件變數。例:


   TypeName obj=new Name(){

   /*此處為類體*/
      }
  同樣,也可以將構造的物件作為呼叫的引數。例:
   
   someMethod(new Name(){
   /*此處為類體*/  });
   3.程式程式碼:
  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());
 
 
 
 }

}
 4.程式執行結果:
   OuterSize=5
   finalLocalVar=47