Java內部類總結

成員內部類

  • 內部類能夠訪問外部類的全部成員。
  • 經過外部類.this.*訪問外部類同名成員。
  • 經過外部類.內部類 name=new 外部類().內部類()實例化對象。
  • 內部類中不能有任何static成員。
public class InnerClass1 {
    public int a;
    protected double b;
    char c;
    private String d;

    InnerClass1(int a){
        this.a=a;
    }

    class inner{
        int a;

        inner(int a){
            this.a=a;
        }

        private void A(){
            System.out.println(a);
            System.out.println(this.a);
            System.out.println(InnerClass1.this.a);
        }

        public void B(){
            System.out.println(b);
        }
    }

    public static void main(String[] args) {
        InnerClass1.inner inner=new InnerClass1(10).new inner(5);
        inner.A();
        inner.B();
    }
}

局部內部類

  • 定義在方法裏,不能有修飾符,只能在方法裏使用。
  • 只能使用外部類的final成員。
  • 除了裝逼暫時想不出這東西有什麼用了...
/**
 * 局部內部類
 */
public class InnerClass2 {

    final static int a=5;

    public static void main(String[] args) {
        class inner{
            int sum(int n){
                int ans=0;
                for(int i=1;i<=n;i++){
                    ans+=i;
                }
                return ans+a;
            }
        }
        System.out.println(new inner().sum(5));
        System.out.println(new inner().sum(15));
    }
}

靜態內部類

  • 靜態內部類較爲獨立,不依賴於外部類,經過外部類.內部類 name=new 外部類.內部類()實例化對象,不須要建立外部類實例。
  • 只能訪問外部類的static成員。
/**
 * 靜態內部類
 */
public class InnerClass3 {

    int a=5;
    static int b=10;

    static class inner3{
        int a=15;
        static int b=20;

        void A(){
            System.out.println(a);
//            System.out.println(InnerClass3.a);
        }

        static void B(){
            System.out.println(b);
            System.out.println(InnerClass3.b);
        }
    }

    public static void main(String[] args) {
        InnerClass3.inner3 inner3=new InnerClass3.inner3();
        inner3.A();
        InnerClass3.inner3.B();
    }
}

匿名內部類

  • 匿名內部類比較常見,好比回調函數,將匿名內部類做爲方法參數傳遞。
  • 直接使用方法就是接口 name=new 接口(){[重寫接口全部函數]}
  • 匿名內部類沒有構造器。
  • 匿名內部類能夠訪問外部方法的局部變量,但必須是final聲明的或者實際不變的。
  • 緣由是當外部方法結束返回時,內部類對象,方法有可能還在,若是引用的外部的局部變量已經沒了,就會發生錯誤,因此經過final修飾,將局部變量複製一份到內部類中,保證數據的一致性。
public class CallBackUser{
    public static void main(String[] args) {

        int b=5;
//        b=5;

        CallBackSystem callBackServer=new CallBackSystem();
        callBackServer.onBtnClick("CallBack", new CallBack() {
            @Override
            public void fun(String name) {
                System.out.println("Hello "+name+" "+b);
            }
        });
    }
}

回調函數

考慮一個問題,如何讓系統調用你寫的一個方法? 好比點擊某個按鈕就執行你寫的方法。java

  • 咱們能夠把本身寫的函數傳給[點擊按鈕]這個函數,在這個函數裏面系統就能調用這個參數(是一個函數),好比Arrays.sort就是一箇中間函數,而傳進去的匿名內部類(別的語言能夠是傳遞函數指針)就是一個回調函數,sort函數內部就會調用這個compare函數去進行比較,排序。
  • 其餘語言好比C++/Python能夠直接把函數做爲另外一個函數的參數傳入,從而進行回調操做。

在Java中實現一個簡單的回調功能須要如下幾步:ide

  • 規定一個統一的接口
    至關於把要回調的函數封裝在這個接口裏面,把實現這個接口的匿名內部類傳遞給調用者(系統)。
public interface CallBack {
    void fun(String name);
}
  • 系統端寫好的API函數
    系統寫API函數的時候不知道用戶具體會傳遞什麼回調函數,只能是根據統一的接口來寫代碼,因此就調用CallBack類型的參數的對應函數。
public class CallBackSystem {

    public void onBtnClick(String name,CallBack callBack){
        System.out.println("點擊按鈕後系統調用你寫的方法");
        callBack.fun(name);
    }
}
  • 用戶調用系統函數,傳入回調函數等待系統回調
    這裏就用到了匿名內部類,由於系統函數的參數是一個接口類型,因此用戶須要一個實現該接口的具體實現類,由於在這裏常常須要不一樣的實現類,因此用匿名內部類是最好的,不須要這個具體的類名。
public class CallBackUser{
    public static void main(String[] args) {
        CallBackSystem callBackServer=new CallBackSystem();
        callBackServer.onBtnClick("CallBack", new CallBack() {
            @Override
            public void fun(String name) {
                System.out.println("Hello "+name);
            }
        });
    }
}
相關文章
相關標籤/搜索