Java的內部類

初識java內部類

內部類:指的是在Java中可以將一個類定義在另一個類的內部。

  • 內部類可以定義在 類的內部 (與類成員層次一致)
  • 內部類可以定義在 方法/塊內部 (與類成員相差一個層次,與方法的局部變量是一個層次)

*1.成員內部類

將一個類直接定義在類的裏面,作爲成員,與屬性或方法層次一致。
成員內部類可以與正常類一樣 使用不同的修飾符(權限的 ,特徵的都行)來修飾
外部類只能使用兩種權限修飾符,(public ,默認不寫)
而內部類可以使用全部的四種權限修飾符,(public, protected ,默認不寫 ,private)
好處1.省略了一個.java源文件
好處2.成員內部類中可以訪問外部類的所有成員 ,包括私有的

public class Demo {
    private String name = "這是正常類中的屬性";
    public void testDemo(){
        System.out.println("這是正常類中的方法");
    }
    //成員內部類
    public class InnerDemo{
        public void testInnerDemo(){
            System.out.println("我是成員內部類的方法"+name);
            testDemo();
        }
    }
}
    public static void main(String[] args) {
        //創建內部類的對象---調用內部類的方法
        Demo.InnerDemo innerDemo = new Demo().new InnerDemo();
        //調用內部類的方法
        innerDemo.testInnerDemo();
    }

輸出結果:
在這裏插入圖片描述
若想要在內部類中通過對象.的方式調用外部類成員,方式爲: 外部類.this.外部類成員;

public class Demo {
    private String name = "這是正常類中的屬性";
    public void testDemo(){
        System.out.println("這是正常類中的testDemo方法");
    }
    //成員內部類
    public class InnerDemo{
        private String name = "我是內部類的屬性";
        public void testDemo(){
            System.out.println("這是內部類中的testDemo方法");
        }
        public void testInnerDemo(){
            System.out.println("我是成員內部類的testInnerDemo方法:"+name);//這個name就是內部類的
            //如果想要訪問外部類的name屬性,應該這樣寫:
            System.out.println("我是成員內部類的方法:"+Demo.this.name);
            testDemo();
            Demo.this.testDemo();
        }
    }
}
    public static void main(String[] args) {
        //創建內部類的對象---調用內部類的方法
        Demo.InnerDemo innerDemo = new Demo().new InnerDemo();
        //調用內部類的方法
        innerDemo.testInnerDemo();
    }

輸出結果:
在這裏插入圖片描述

內部類存在後 源代碼進行編譯 產生一個字節碼 Demo$InnerDemo.class
我們可以看出,美元符號其實就是內部類命名的標誌。
在這裏插入圖片描述

2.局部內部類

將一個類定義在方法/塊裏面,作爲成員的內部結構,與臨時的局部變量一個層次。
局部內部類是臨時存在的,方法執行完,這個類的空間就被自動回收了。
局部內部類像是一個局部的變量一樣,不能用public protected private及static
只能用abstract或final。
【小技巧】:在類中寫一個空的main函數,讓它去執行, 可以讓該類立即被編譯,生成.class文件。
在這裏插入圖片描述
局部內部類命名規則:
Demo$1InnerTestOneDemo
Demo$2InnerTestOneDemo
出現內部類重名以後,會有數字將它們區分開,1表示第1次出現的內部類,2表示第2次出現的內部類。

public class Demo {
    private String name = "這是正常類中的屬性";
    public void testDemo(){
        System.out.println("這是正常類中的testDemo方法");
    }
    public void testDemoOne(){
        String s = "abc";
        //在方法中定義一個局部內部類
        class InnerTestOneDemo{
            //局部內部類使用的變量都需要加final來修飾
        }
    }
    {
        //在塊中定義一個局部內部類,與方法中那個內部類重名了
        class InnerTestOneDemo{
            //局部內部類使用的變量都需要加final來修飾
        }
    }
}

*局部內部類使用的變量只能是final修飾,爲什麼?
因爲局部內部類是類加載的時候就編譯好了,編譯好的.class文件是不能改變的,如果局部內部類中的變量不使用final修飾,讓變量隨意去改變,就會產生衝突。

*3.匿名內部類

成員匿名內部類
局部匿名內部類

不用匿名內部類,以前我們這樣寫:

public interface Test {
    public void test();
}
public class Son implements Test{
    @Override
    public void test() {
        //······
    }
}
    public static void main(String[] args) {
        Test t = new Son();
        t.test();
    }

有了匿名內部類以後,我們可以這樣寫:

public interface Test {
    public void test();
}
    public static void main(String[] args) {
        Test t = new Test(){
            public void test() {
                //······
            }
        };//分號不可省略
    }

new Test()後面的大括號裏放的是匿名內部類的所有類成員。
通常接口或抽象類的具體子類這樣寫。
開發中爲了省略一個類文件 , 上述寫法比較常見。
匿名內部類很特殊, 只有類體, 沒有類的( 修飾符 名字 繼承 實現)。
不能用任何修飾符來修飾, 匿名內部類也沒有構造方法。
應用:Swing 做一個按鈕 ,綁定一個事件監聽器

4.靜態內部類

成員靜態內部類
不需要外部類對象,通過正常的方式直接創建內部類即可!(前提是先導好包)
靜態元素不能訪問非靜態成員(自己類和外部類的非靜態成員都不行)。

public class Demo {

    //靜態內部類
    public static class InnerDemoStatic{

    }
}
package innerclass;
import innerclass.Demo.InnerDemoStatic;
public class TestMain {
    public static void main(String[] args) {
        InnerDemoStatic innerStatic = new InnerDemoStatic();
    }
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章