1. 程式人生 > >java基礎——————內部類 靜態內部類、成員內部類、匿名內部類

java基礎——————內部類 靜態內部類、成員內部類、匿名內部類

內部類包括四種類型:靜態內部類,例項(成員)內部類,匿名內部類,本地內部類(不多用)
主要分析前三種內部類的建立以及物件的建立和方法的如何呼叫

一、靜態內部類

1)訪問內部類的資料成員和方法

訪問內部類資料成員方法: 內部類物件直接呼叫
內部類物件呼叫外部類非靜態資料成員和方法內部類物件 . 外部類物件. 方法或者變數
在內部類呼叫外部類靜態資料成員或方法: 外部類名直接呼叫

1)) 通過在內部類中寫入一個傳入外部類物件的建構函式,以此建立內部類的物件,通過內部類物件呼叫內部類的資料成員和方法

//   此程式碼處於內部類中
  OuterClass outer;  // 建立一個外部類型別的成員變數
        public InnerClass(OuterClass outer) {       //  靜態內部類構造方法(傳入的是外部類的物件)
            this.outer = outer;
        }
2))    **建立內部類物件,  內部類物件可以呼叫內部類物件,此外也可以呼叫外部類物件和方法**;  	  	
public static void  main{
 //  建立靜態內部類的物件,首先要建立一個外部類物件,把外部類物件傳給靜態內部類
        OuterClass outer=new OuterClass();
        OuterClass.InnerClass inner =new OuterClass.InnerClass(outer);   //   >>>>>建立了靜態內部類物件 inner
	        inner.fun();         // 通過靜態內部類物件呼叫內部類的成員方法
            inner.outer.eat();//  **通過靜態內部類物件呼叫外部類的成員方法** 
}

二、例項內部類(成員內部類)

1:例項內部類中可以可以定義靜態變數,但是必須由final 修飾
2:例項內部類不可以定義靜態方法;
3: 例項內部類的物件建立方法:
外部類名 .例項內部類名 物件名 =new 外部類名(). new 內部類名();
如果已經有外部物件,則可以寫成:
外部類名 .例項內部類名 物件名 =外部類物件 . new 內部類名();

4:在外部類中呼叫內部類的方法: !!!!外部類不能呼叫內部類封裝的資料或者方法
定義一個內部類型別的變數,然後在外部類中構造方法,new出一個例項,

	 InnerClass2 in;  //  在外部類定義一個內部類型別的變數
    public  OuterClass() {
        in= new InnerClass2();    //在外部類中構造方法,new出一個例項,	
    }
    void fun() {  
        System.out.println(in.data5);  // 呼叫例項內部類的資料  !!!注意,外部類不能呼叫內部類封裝的資料或者方法
    }

4: 在內部類中呼叫外部類的方法: 使用this關鍵字: 外部類名.this.外部類變數或方法

 System.out.println(OuterClass.this.data1); //  內部類呼叫外部類的資料成員或方法要使用this關鍵字

三、 匿名內部類

1:使用匿名內部類時,我們必須是繼承一個類或者實現一個介面,但是兩者不可兼得,同時也只能繼承一個類或者實現一 個介面。
2:匿名內部類中不能存在任何的靜態成員變數和靜態方法。
3:當所在的方法的形參需要被內部類裡面使用時,該形參必須為final。
格式:
new 外部類名 ( ) {
… 裡面可以寫方法
} . 外部類裡面的方法;

class outer{
        void fly() {
            System.out.println(" fly ");
        }
}

public class testDemo9 {
    static void fun(outer chicken){
        chicken.fly();
    }
    public  static void main(String [] args){
        new outer(){
            void fly() { 				  //重寫了父類的方法  此處可不寫程式碼
                System.out.println("fly!!!")
            }
        }.fly();

    }
}

測試程式碼:(成員內部類和靜態內部類)

public class OuterClass {
    public int data1;
    private int data2;
    private static int data3;

    {
        data1 = 999;
        data2 = 888;
        data3 = 777;
    }

    // 外部類呼叫例項內部類的資料成員需要有例項
    InnerClass2 in;
    public  OuterClass() {
        in= new InnerClass2();
    }
    void fun() {
        System.out.println(in.data5);  // 呼叫例項內部類的資料  !!!注意,外部類不能呼叫內部類封裝的資料或者方法
    }

    public void eat() {
        System.out.println("  eatting  ");
    }

    //*****************************************靜態內部類***********************************************
    static class InnerClass {
        public int data4;
        public int data5;
        OuterClass outer;  // 建立一個外部類型別的成員變數

        public InnerClass(OuterClass outer) {  //  靜態內部類構造方法(傳入的是外部類的物件)
            this.outer = outer;
        }

        public void fun() {   // 靜態內部類的方法
            System.out.println("this is innerclass");
            System.out.println(outer.data1); //使用靜態內部類呼叫外部類的非靜態資料成員或者方法
            outer.eat();                    //必須使用傳入進來的外部類物件來呼叫
            System.out.println(OuterClass.data3);   //  直接用外部類名呼叫外部類的靜態變數

        }

    }

    // ***********************************例項內部類**************************************************************
    public class InnerClass2 {
        private int data3 = 100;
        public int data5 = 10;
        //private static  int DATA4 = 1000;error
        private static final int DATA4 = 1000;    // 靜態變數必須要拿final修飾
        //private static final int DATA5 = data5; error,靜態變數必須給實體資料值;

        public void InnerClass2() {    //  例項內部類的方法
            System.out.println("InnerClass2().init");
            System.out.println(OuterClass.this.data1); //  內部類呼叫外部類的資料成員或方法要使用this關鍵字
        }
    }


    public static void main(String[] args) {
        //*************靜態內部類相關***************************************
        //  建立靜態內部類的物件,首先要建立一個外部類物件,把外部類物件傳給靜態內部類
        OuterClass outer = new OuterClass();
        OuterClass.InnerClass inner = new OuterClass.InnerClass(outer);   //   >>>>>建立了靜態內部類物件 inner
        inner.fun();  // 通過靜態內部類物件呼叫內部類的成員方法
        inner.outer.eat();//  通過靜態內部類物件呼叫外部類的成員方法
        //***************例項內部類相關*********************************************
            // 建立例項內部類的物件
        //  外部類名 .例項內部類名 物件名 =new 外部類名(). new  內部類名();
        // 如果已經有外部物件,可以直接
        //  外部類名 .例項內部類名 物件名 =外部物件. new  內部類名();
          OuterClass.InnerClass2 inner2 = outer.new InnerClass2();


    }
}

測試程式碼: 匿名內部類

class brid{
        void fly() {
            System.out.println(" fly ");
        }
}

public class testDemo9 {
    static void fun(brid chicken){
        chicken.fly();
    }
    public  static void main(String [] args){
        new brid(){
            void fly() {   //重寫了父類的方法
                System.out.println("fly!!!");
            }
        }.fly();

    }
}