Java中的內部類

java中的內部類分爲:靜態內部類、成員內部類、局部內部類、匿名內部類java

成員內部類(相似成員變量):ide

public class InnerClassTest {

    public class InnerClassA {
        
    }
}
  • 成員內部類依賴外部類而存在的
  • 成員內部類能夠外部類全部的字段,外部類經過成員內部類的引用來訪問內部類全部的字段
public class InnerClassTest {

    public int outField1 = 1;
    protected int outField2 = 2;
    int outField3 = 3;
    private int outField4 = 4;

    public InnerClassTest() {
        // 在外部類對象內部,直接經過 new InnerClass(); 建立內部類對象
        InnerClassA innerObj = new InnerClassA();
        System.out.println("建立 " + this.getClass().getSimpleName() + " 對象");
        System.out.println("其內部類的 field1 字段的值爲: " + innerObj.field1);
        System.out.println("其內部類的 field2 字段的值爲: " + innerObj.field2);
        System.out.println("其內部類的 field3 字段的值爲: " + innerObj.field3);
        System.out.println("其內部類的 field4 字段的值爲: " + innerObj.field4);
    }

    public class InnerClassA {
        public int field1 = 5;
        protected int field2 = 6;
        int field3 = 7;
        private int field4 = 8;
//        static int field5 = 5; // 編譯錯誤!普通內部類中不能定義 static 屬性

        public InnerClassA() {
            System.out.println("建立 " + this.getClass().getSimpleName() + " 對象");
            System.out.println("其外部類的 outField1 字段的值爲: " + outField1);
            System.out.println("其外部類的 outField2 字段的值爲: " + outField2);
            System.out.println("其外部類的 outField3 字段的值爲: " + outField3);
            System.out.println("其外部類的 outField4 字段的值爲: " + outField4);
        }
    }

    public static void main(String[] args) {
        InnerClassTest outerObj = new InnerClassTest();
        // 不在外部類內部,使用:外部類對象. new 內部類構造器(); 的方式建立內部類對象
//        InnerClassA innerObj = outerObj.new InnerClassA();
    }
}

靜態內部類(相似靜態成員變量):this

  • 靜態內部類獨立於外部類而存在,只要在具備訪問權限的地方,經過類名.靜態成員名訪問:
public class InnerClassTest {
	public int field1 = 1;
    
	public InnerClassTest() {
		System.out.println("建立 " + this.getClass().getSimpleName() + " 對象");
        // 建立靜態內部類對象
        StaticClass innerObj = new StaticClass();
        System.out.println("其內部類的 field1 字段的值爲: " + innerObj.field1);
        System.out.println("其內部類的 field2 字段的值爲: " + innerObj.field2);
        System.out.println("其內部類的 field3 字段的值爲: " + innerObj.field3);
        System.out.println("其內部類的 field4 字段的值爲: " + innerObj.field4);
    }
	
    static class StaticClass {

        public int field1 = 1;
        protected int field2 = 2;
        int field3 = 3;
        private int field4 = 4;
        // 靜態內部類中能夠定義 static 屬性
        static int field5 = 5;

        public StaticClass() {
            System.out.println("建立 " + StaticClass.class.getSimpleName() + " 對象");
//            System.out.println("其外部類的 field1 字段的值爲: " + field1); // 編譯錯誤!!
        }
    }

    public static void main(String[] args) {
	    // 無需依賴外部類對象,直接建立內部類對象
//        InnerClassTest.StaticClass staticClassObj = new InnerClassTest.StaticClass();
		InnerClassTest outerObj = new InnerClassTest();
    }
}
  • 靜態內部類只能訪問外部類的靜態成員
  • 外部類能夠訪問靜態內部類的全部字段

匿名內部類:spa

public class InnerClassTest {

    public int field1 = 1;
    protected int field2 = 2;
    int field3 = 3;
    private int field4 = 4;

    public InnerClassTest() {
        System.out.println("建立 " + this.getClass().getSimpleName() + " 對象");
    }
    // 自定義接口
	interface OnClickListener {
        void onClick(Object obj);
    }

    private void anonymousClassTest() {
        // 在這個過程當中會新建一個匿名內部類對象,
        // 這個匿名內部類實現了 OnClickListener 接口並重寫 onClick 方法
        OnClickListener clickListener = new OnClickListener() {
	        // 能夠在內部類中定義屬性,可是隻能在當前內部類中使用,
	        // 沒法在外部類中使用,由於外部類沒法獲取當前匿名內部類的類名,
	        // 也就沒法建立匿名內部類的對象
	        int field = 1;
	        
            @Override
            public void onClick(Object obj) {
                System.out.println("對象 " + obj + " 被點擊");
                System.out.println("其外部類的 field1 字段的值爲: " + field1);
                System.out.println("其外部類的 field2 字段的值爲: " + field2);
                System.out.println("其外部類的 field3 字段的值爲: " + field3);
                System.out.println("其外部類的 field4 字段的值爲: " + field4);
            }
        };
        // new Object() 過程會新建一個匿名內部類,繼承於 Object 類,
        // 並重寫了 toString() 方法
        clickListener.onClick(new Object() {
            @Override
            public String toString() {
                return "obj1";
            }
        });
    }

    public static void main(String[] args) {
        InnerClassTest outObj = new InnerClassTest();
        outObj.anonymousClassTest();
    }
}
  • new 一個已經存在的類,並選擇性實現這個類中一個或多個非final的方法
  • 匿名內部類能夠訪問外部類的屬性,外部類不能訪問匿名內部類的屬性(由於是匿名內部類,外部類無獲取它的類名)

局部內部類(相似匿名內部類):code

  • 比較少使用,聲明在方法體/代碼塊內部。匿名內部類實現能夠實現它的功能,同時更爲簡潔。
public class InnerClassTest {

    public int field1 = 1;
    protected int field2 = 2;
    int field3 = 3;
    private int field4 = 4;

    public InnerClassTest() {
        System.out.println("建立 " + this.getClass().getSimpleName() + " 對象");
    }
    
    private void localInnerClassTest() {
	    // 局部內部類 A,只能在當前方法中使用
        class A {
	        // static int field = 1; // 編譯錯誤!局部內部類中不能定義 static 字段
            public A() {
	            System.out.println("建立 " + A.class.getSimpleName() + " 對象");
                System.out.println("其外部類的 field1 字段的值爲: " + field1);
                System.out.println("其外部類的 field2 字段的值爲: " + field2);
                System.out.println("其外部類的 field3 字段的值爲: " + field3);
                System.out.println("其外部類的 field4 字段的值爲: " + field4);
            }
        }
        A a = new A();
        if (true) {
	        // 局部內部類 B,只能在當前代碼塊中使用
            class B {
                public B() {
	                System.out.println("建立 " + B.class.getSimpleName() + " 對象");
                    System.out.println("其外部類的 field1 字段的值爲: " + field1);
                    System.out.println("其外部類的 field2 字段的值爲: " + field2);
                    System.out.println("其外部類的 field3 字段的值爲: " + field3);
                    System.out.println("其外部類的 field4 字段的值爲: " + field4);
                }
            }
            B b = new B();
        }
//        B b1 = new B(); // 編譯錯誤!不在類 B 的定義域內,找不到類 B,
    }

    public static void main(String[] args) {
        InnerClassTest outObj = new InnerClassTest();
        outObj.localInnerClassTest();
    }
}
  • 外部類沒法訪問局部內部類的字段,局部內部類能夠訪問外部類的字段
相關文章
相關標籤/搜索