淺談Java內部類

1、什麼是Java內部類?ide

能夠將一個類的定義放在另外一個類的內部,這就是內部類。廣義上咱們將內部類分爲四種:成員內部類、靜態內部類、局部(方法)內部類、匿名內部類。this

2、爲何用內部類?.net

使用內部類最新引人的緣由是:每一個內部類都能獨立地繼承一個接口的實現,因此不管外部類是否已經繼承了某個接口,對於內部類都沒有影響。code

在實際問題中咱們遇到一些接口沒法解決的問題,此時咱們能夠使用內部類繼承某個具體的或抽象的類,簡介解決類沒法多繼承引發的一系列問題。對象

除了上面的有點外還有以下四個優勢:blog

一、內部類能夠用多個實例,每一個實例都有本身的狀態信息,而且與其它外部對象的信息相互獨立。繼承

二、內部類並無使人迷惑的「is-a」關係,他就是一個獨立的實體。接口

注:is-a爲父子繼承關係生命週期

三、內部類提供了更好地封裝,除了外部類,其餘類不能訪問。get

四、建立內部類對象的時刻並不依賴於外部類對象的建立。

3、如何使用內部類

(一)成員內部類

一、直接上代碼

package innerClass;
public class Outer {
    private int outerVariable = 1;
    private int commonVariable = 2;
    private static int outerStaticVariable = 3;
    //成員方法
    public void outerMethod() {
        System.out.println("我是外部類的outerMethod方法");
    }
     //靜態方法
    public static void outerStaticMethod() {
        System.out.println("我是外部類的outerStaticMethod靜態方法");
    }
    /**
     * 內部類
     */
    public class Inner {
        private int commonVariable = 20;
         //構造方法
        public Inner() {
        }
         //成員方法,訪問外部類信息(屬性、方法)
        public void innerShow() {
            //當和外部類衝突時,直接引用屬性名,是內部類的成員屬性
            System.out.println("內部的commonVariable:" + commonVariable);
            //內部類訪問外部屬性
            System.out.println("outerVariable:" + outerVariable);
            //當和外部類屬性名重疊時,可經過外部類名.this.屬性名
            System.out.println("外部的commonVariable:" + Outer.this.commonVariable);
            System.out.println("outerStaticVariable:" + outerStaticVariable);
            //訪問外部類的方法
            outerMethod();
            outerStaticMethod();
         }
    }

    //外部類訪問內部類信息
    public void outerShow() {
        Inner inner = new Inner();
        inner.innerShow();
    }

    public static void main(String[] args) {
        Outer outer = new Outer();
        Outer.Inner inner = outer.new Inner();
        outer.outerShow();
        inner.innerShow();
    }
}

二、運行結果

三、小結:

① 能夠是任何的訪問修飾符

② 內部類的內部不能有靜態信息

③ 內部類也是類,可繼承,可重寫,可重載,this和super隨便用

④ 外部類必須經過new才能訪問內部類

⑤ 內部類能夠直接使用外部類的任何信息,若是屬性或方法名一致,調用外部類.this.屬性或方法。

(二)靜態內部類

一、直接上代碼

package innerClass;

public class Outer1 {
    private int outerVariable = 1;

    //外部類定義的屬性(重名)
    private int commonVariable = 2;
    private static int outerStaticVariable = 3;
    static {
        System.out.println("Outer的靜態塊被執行了……");
    }

    //成員方法
    public void outerMothod() {
        System.out.println("我是外部類的outerMethod方法");
    }

    //靜態方法
    public static void outerStaticMethod() {
        System.out.println("我是外部類的outerStaticMethod靜態方法");
    }

    //靜態內部類
    public static class Inner {
        private int innerVariable = 10;
        private int commonVariable = 20;

        static {
            System.out.println("Outer.Inner的靜態塊執行了……");
        }

        private static int innerStaticVariable = 30;

        //成員方法
        public void innerShow() {
            System.out.println("innerVariable:" + innerVariable);
            System.out.println("內部的commonVariable:" + commonVariable);
            System.out.println("outerStaticVariable:"+outerStaticVariable);
            outerStaticMethod();
        }

        //靜態方法
        public static void innerStaticShow() {
            //被調用時會先加載Outer類
            outerStaticMethod();
            System.out.println("outerStaticVariable"+outerStaticVariable);
        }
    }

   //外部類的內部如何和內部類打交道
    public static void callInner() {
        System.out.println(Inner.innerStaticVariable);
        Inner.innerStaticShow();
    }

    public static void main(String[] args) {
        Outer1 outer1 = new Outer1();
        Outer1.Inner inner = new Outer1.Inner();
        outer1.callInner();
        Inner.innerStaticShow();
        inner.innerShow();
    }
}

二、運行結果

三、小結:

① 內部能夠包含任何信息

② 靜態內部類的方法只能訪問外部類的static的信息

③ 調用內部非靜態方法(成員方法)

Outer.Inner inner = new Outer.Inner();

inner.inerShow();

④ 調用內部靜態方法

Inner.innerStaticShow();

(三)局部(方法)內部類

一、直接上代碼

public class Outer {
    public class Inner {
        private int commonVariable = 20;
         //構造方法
        public Inner() {
        }
         //成員方法,訪問外部類信息(屬性、方法)
        public void innerShow() {
            class Inner2 {
                public void inner2Show(){
                    System.out.println("方法內部類");
                }
            }

            Inner2 inner2 = new Inner2();
            inner2.inner2Show();
         }
    }
}

輸出結果可想而知,不寫了

局部內部類只能在方法內使用。

(四)匿名內部類

一、直接上代碼

public interface IAnimal {
    void speak();
}
public class animalOuter {
    public static IAnimal getInnerInstance(final String msg){
        return new IAnimal() {
            @Override
            public void speak(String str) {
                System.out.println(str+" is " + msg);
            }
        };
    }

    public static void main(String[] args) {
        animalOuter.getInnerInstance("江疏影").speak("my name");
    }
}

二、運行結果

三、小結:

① 匿名內部類沒有訪問修飾符

② 使用匿名內部類時,要重寫這個匿名的內部類

③ 匿名內部類訪問方法參數時也有和局部內部類一樣的限制。

④ 匿名內部類沒有構造方法。

⑤ 方法的參數必須用final修飾,這是爲何呢?

感謝@Ken大神的賜教,受益不淺啊

局部變量的生命週期與內部類對象的生命週期不同,頗有可能局部變量死了,內部類對象還活着,因此定義爲final,至關於拷貝一份局部變量供內部類對象調用

 

素小暖講Java@目錄

相關文章
相關標籤/搜索