1. 程式人生 > >Java學習——內部類的定義與使用

Java學習——內部類的定義與使用

內部類


定義:在一個類的內部進行其他類結構的巢狀。

先寫一個內部類

class Outer{
    private String msg = "Hello World";
    //=============內部類==================
    class Inner{
        public void print(){
            System.out.println(Outer.this.msg);//呼叫Outer的private屬性
        }
    }
    //=============內部類==================
    //產生一個內部類物件並呼叫內部類的print方法
    public void fun(){
        new Inner().print();
    }
}
public class Test{
    public static void main(String[] args) {
        Outer ou = new Outer();
        ou.fun();
    }
}

引入內部類後,程式的結構有些混亂。雖然內部類破壞了程式的結構,但是從另一方面來講,內部類可以方便的操作外部類的私有訪問。

如果這個操作不用內部類來寫,會是什麼情況呢?

class Outer{
    private String msg = "Hello World";
    public String getMsg(){
        return msg;
    }
    public void fun(){
        new Inner().print(this);
    }
}
class Inner{
    public void print(Outer ou){
        System.out.println(ou.getMsg());
    }
}
public class Test{
    public static void main(String[] args) {
        Outer ou = new Outer();
        ou.fun();
    }
}

可見程式碼比上面的複雜了一些,要寫get函式獲取outer類的私有屬性。

內部類存在的意義:

1.內部類與外部類可以互相訪問彼此的私有域(最大優點)

2.內部類可以實現Java的單繼承侷限

3.內部類可以對同一包中的其他類隱藏起來,僅供外部類使用(保護性)

缺點:結構複雜

內部類分類

1.成員內部類——對比成員方法理解

a.成員內部類不能存在任何static變數或方法,但可以訪問外部類的靜態域;(成員內部類需要依附外部類的建立而建立,而static變數或方法與物件無關,即便沒有外部類也可以建立static變數或方法,這就與前面矛盾)

b.成員內部類需要依附外部類——new Outter().new Inner();先建立外部類再建立內部類;

c.內部類可以使用private封裝,表示私有內部類,該內部類僅供外部類使用(如HaspMap中的Entry內部類,ArrayList中的Node內部類)

2.靜態內部類-用static修飾——對比靜態方法理解

a.靜態內部類的建立不需要外部類,可以直接建立

b.靜態內部類不可以訪問外部類的任何非static域,但可以存在成員變數

3.方法內部類

class Outer{
    private String msg = "Hello World";
    public void fun(){
        class Inner{
            public void print(){
                System.out.println(Outer.this.msg);//呼叫Outer的private屬性
            }
        }
        new Inner().print();;
    }
}
public class Test{
    public static void main(String[] args) {
        Outer ou = new Outer();
        ou.fun();
    }
}

1.方法內部類不能使用任何訪問許可權修飾符(如public、private)

2.方法內部類對外(方法外)完全隱藏,除了該方法可以訪問它之外,其餘地方均不能訪問

3.方法內部類要想使用方法形參,該形參必須使用final宣告(jdk8變為隱式final宣告)

4.匿名內部類——方法內部類的特殊版本——lambda表示式的第一步

1.沒有訪問許可權修飾符

2.匿名內部類必須繼承一個抽象類或者實現一個介面

3.匿名內部類沒有構造方法,因為它沒有類名

interface Iif{
    public void display();
}
class Test{
    public static void main(String[] args) {
        new Iif(){
            @Override
            public void display(){
                System.out.println("匿名內部類");
            }
        }.display();
    }
}   

建立內部類

建立內部類的語法(在外部類的外部)

建立非靜態內部類

外部類.內部類  內部類引用 = new  外部類().new  內部類();

Outer.Inner  in = new Outter().new Inner();

之所以要先進行外部類物件的例項化,因為此時外部類存在普通屬性,這些屬性必須進行例項化後才能訪問。 

如果說現在一個內部類只想被外部類使用,即:不希望直接產生內部類的例項化物件,可以使用private定義。

在進行屬性訪問時,都需要加上this關鍵字。所以如果想在內部類中明確的使用this,那麼語法形式如下:外部類.this.屬性

建立靜態內部類

外部類.內部類 內部類引用 = new 外部類.內部類();

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

內部類與外部類的關係

1.對非靜態內部類而言,內部類的建立需要依賴外部類的例項化物件,在沒有外部類物件之前是無法建立內部類的。

2.內部類是一個相對獨立的個體,與外部類也不是繼承關係。

3.內部類可以直接訪問外部類的元素(包含私有域),但是外部類不可以直接訪問內部類元素,需要通過內部類的引用間接訪問。