1. 程式人生 > >內部類使用及注意事項

內部類使用及注意事項

什麼叫內部類呢?

簡單來說將一個類定義到另一個類裡面,裡面那個類就稱為是內部類

內部類的訪問特點:

內部類可以直接訪問外部類中的成員,包括私有成員。外部類要訪問內部類中的成員必須要建立內部類的物件才能訪問。

內部類的用處:

內部類一般用於類的設計。分析事物時,發現該事物描述中還有事物,而且這個事物還在訪問被描述事物的內容。這個時候,這個事物中的事物就定義成內部類來描述。

內部類的修飾符:

由於內部類被定義在成員位置,所以內部類可以被成員修飾符修飾。

內部類可以在其他類中直接訪問,例:

class Outer{
        private
int num=3; class Inner{ void show(){ System.out.println("show run"+num); } } public void method(){ Inner in = new Inner(); in.show(); } } class InnerDemo{ public static void main(String[]args){ //直接訪問外部類中的內部類中的成員。
Outer.Inner in =new Outer().new Inner(); in.show(); } }

如果內部類是靜態的,其實相當於一個外部類。可以直接用外部類的物件呼叫內部類類名使用,例:

class Outer{
        private static int num=3;
        static class Inner{
            void show(){
                System.out.println("show run"+num);
            }
        }
        public
static void method(){ Inner in = new Inner(); in.show(); } } class InnerDemo{ public static void main(String[]args){ Outer.Inner in =new Outer.Inner(); in.show(); } }

如果內部類中定義了靜態的成員,該內部類也必須定義成靜態的否則會編譯失敗,例:

class Outer{
        private static int num=3;
         class Inner{
            void show(){
                System.out.println("show run"+num);
            }
            public static void function(){
                System.out.println("function 運行了");
            }
        }
        public static void method(){
            Inner in = new Inner();
            in.show();
        }
    }

    class InnerDemo{
        public static void main(String[]args){
            Outer.Inner.function();
        }   
    }

結果為:
Compiling InnerDemo.java……
InnerDemo.java:63: 錯誤: 內部類Outer.Inner中的靜態宣告非法
public static void function(){
^
修飾符 ‘static’ 僅允許在常量變數宣告中使用
InnerDemo.java:68: 錯誤: 無法從靜態上下文中引用非靜態 變數 this
Inner in = new Inner();
^
2 個錯誤
[Finished in 0.6s]

為什麼內部類可以直接訪問外部類的成員:

因為內部類被定義在外部類的成員位置,該內部類就持有了外部類的引用(外部類名.this)

內部類可以放在區域性位置上 ,例:

public class InnerDemo2{
    public static void main(String[]args){
        new Outer().method();
    }
}
class Outer{
    int num=3;
    void method(){
        class Inner{
            void show(){
                System.out.println("show......"+num);
            }
        }
        Inner in = new Inner();
        in.show();
    }
}

當內部類處於區域性位置時,該內部類只能訪問區域性中被final修飾的區域性變數。

public class InnerDemo2{
    public static void main(String[]args){
        Outer out = new Outer();
        Object obj = out.method();
    }
}
class Outer{
    final int num=3;
    Object method(){
        int x = 9;
        class Inner{
            void show(){
                System.out.println("show......"+x);
            }
        }
        Object in = new Inner();
        // in.show();
        return in;
    }
}   

匿名內部類:

匿名內部類其實就是內部類的簡寫格式,是一個匿名 的子類物件,可以直接在類的結束部分加點呼叫。
簡寫的前提:內部類必須實現或者繼承一個外部類或者介面

public class InnerDemo3{
    public static void main(String []args){
        new Outer().method();
    }
}

abstract class Demo{
    abstract void show();
}

class Outer{
    int num=4;
    public void method(){
        new Demo(){
            void show(){
                System.out.println("show......"+num);
            }
        }.show();
    }
}

匿名內部類的使用場景:

當函式引數是介面型別時,且介面中的方法不超過三個,這個時候就可以用匿名內部類作為實際引數進行傳遞。

使用匿名內部類的注意事項:

當在建立內部類物件的時候可以呼叫子類特有的方法,當建立物件的父類引用型別時,就不能引用子類特有的方法了,因為物件已經向上進行了轉型。
例:1.在建立時呼叫

public class InnerDemo5{
    public static void main(String[]args){
        new Outer().method();
    }
}

class Outer{
    void method(){
        new Object(){
            public void show(){
                System.out.println("show run");
            }
        }.show();
    }
}

結果如下:

Compiling InnerDemo5.java……
——Output——
show run
[Finished in 0.6s]
2.建立子類物件的父類引用型別時,呼叫子類特有的方法

public class InnerDemo5{
    public static void main(String[]args){
        new Outer().method();
    }
}

class Outer{
    void method(){
        Object obj = new Object(){
            public void show(){
                System.out.println("show run");
            }
        };
        obj.show();
    }
}

執行結果如下:

Compiling InnerDemo5.java……
InnerDemo5.java:14: 錯誤: 找不到符號
obj.show();
^
符號: 方法 show()
位置: 型別為Object的變數 obj
1 個錯誤
——Output——
[Finished in 0.6s]