你真的了解java內(nèi)部類(lèi)嗎?

關(guān)于java內(nèi)部類(lèi)的一些總結(jié)

匿名內(nèi)部類(lèi)了解一下?其實(shí)你每天都在用。

概念

將一個(gè)類(lèi)聲明在另一個(gè)類(lèi)的內(nèi)部,則將這個(gè)類(lèi)成為內(nèi)部類(lèi)。其與外部類(lèi)互相訪問(wèn)規(guī)則如下:

  • 內(nèi)部類(lèi)可以訪問(wèn)外部類(lèi)的一切成員,包括私有成員;
  • 外部類(lèi)若想訪問(wèn)內(nèi)部類(lèi)的成員,則必須聲明內(nèi)部類(lèi)的實(shí)例對(duì)象。

這個(gè)規(guī)則可以這么理解,外部類(lèi)和內(nèi)部類(lèi)就像父母和孩子:不管孩子要什么,父母總是會(huì)滿足;但孩子有獨(dú)立意識(shí)后,父母想了解孩子,就必須先得到孩子的同意才可以。

雖說(shuō)有了規(guī)則限制,但內(nèi)部類(lèi)又可以劃分為普通內(nèi)部類(lèi),靜態(tài)內(nèi)部類(lèi)以及匿名內(nèi)部類(lèi),因此在實(shí)際使用的時(shí)候,難免還是會(huì)有迷惑的地方。下面,用偽代碼進(jìn)行一下區(qū)別展示。

普通內(nèi)部類(lèi)的調(diào)用

class Outer{
    private int value = 10;
    class Inner{
        private int value = 20;
        void showValue(){
            int value = 30;
            System.out.print("this is funcValue -> " + value); //30
            System.out.print("this is innerValue -> " + this.value); //20
            System.out.print("this is outerValue -> " + Outer.this.value); //10
        } 
    }
}

public class Test {
    public static void main(String[] str) {
        // 普通內(nèi)部類(lèi),實(shí)例化內(nèi)部類(lèi)對(duì)象時(shí),需要先實(shí)例化Outer類(lèi)對(duì)象,然后用Outer類(lèi)對(duì)象實(shí)例化Inner類(lèi)對(duì)象
        Outer.Inner inner = new Outer().new Inner(); 
        inner.showValue();
    }
}

靜態(tài)內(nèi)部類(lèi)的調(diào)用

當(dāng)一個(gè)類(lèi)為內(nèi)部成員時(shí),其便可以像其他內(nèi)部屬性、方法一樣,被各種成員修飾符所修飾。

靜態(tài)內(nèi)部類(lèi)有兩個(gè)需要注意的點(diǎn):

  • 因?yàn)楸宦暶鳛殪o態(tài),所以只能訪問(wèn)外部類(lèi)中同樣的靜態(tài)屬性、方法等;
  • 當(dāng)一個(gè)類(lèi)為靜態(tài)內(nèi)部類(lèi)時(shí),外部類(lèi)對(duì)其的調(diào)用方式也會(huì)發(fā)生不同
class Outer{
     private static int outStaticValue = 10;
     private int outValue = 11;
     static class Inner{
        void showValue(){
            System.out.print("this is static Inner " + outStaticValue); // 可以訪問(wèn)
            System.out.print("this is static Inner " + outValue); // 編譯不通過(guò)
        } 
    }
}

public class Test {
    public static void main(String[] str) {
        // 靜態(tài)內(nèi)部類(lèi),實(shí)例化靜態(tài)內(nèi)部類(lèi)對(duì)象時(shí),直接通過(guò)Outer.Inner獲取內(nèi)部類(lèi)即可
        Outer.Inner inner = new Outer.Inner(); 
        inner.showValue();
    }
}

匿名內(nèi)部類(lèi)的調(diào)用

我們都熟悉匿名對(duì)象的用法,最簡(jiǎn)單的如 new Object().toString(),便是匿名對(duì)象的基本使用了。

同理,匿名內(nèi)部類(lèi)也是類(lèi)似的。

但是也有不同,那就是聲明匿名內(nèi)部類(lèi),要求類(lèi)必須繼承一個(gè)抽象類(lèi)或者實(shí)現(xiàn)一個(gè)接口。

下面看一下正常邏輯實(shí)現(xiàn),以及匿名內(nèi)部類(lèi)實(shí)現(xiàn)的代碼示例。

  • 正常邏輯實(shí)現(xiàn)調(diào)用
abstract class ParentClass{
    abstract void show();  
}

class Outer{
    class Inner extends ParentClass{
        @Override
        void show() {}
    } 
    void func(){
        new Inner().show();
    }
}

public class Test {
    public static void main(String[] str) {
        // 正常邏輯實(shí)現(xiàn)調(diào)用
        new Outer().func();
    }
}
  • 匿名內(nèi)部類(lèi)實(shí)現(xiàn)方式
abstract class ParentClass{
    abstract void show();  
}

class Outer{
    void func(){
        new ParentClass(){
            @override
            void show() {}
        };
    }
}

public class Test {
    public static void main(String[] str) {
        new Outer().func();
    }
}

其實(shí)匿名內(nèi)部類(lèi)很簡(jiǎn)單,說(shuō)到底就是new Parent(){實(shí)現(xiàn)父類(lèi)或者接口的抽象方法}

是不是覺(jué)得很眼熟?沒(méi)錯(cuò),我們基本上每天都在用:

mButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {}
        });

View.OnClickListener是一個(gè)抽象接口,我們這種實(shí)現(xiàn)方式,其實(shí)就是匿名內(nèi)部類(lèi)的實(shí)現(xiàn)。

定義在方法中的內(nèi)部類(lèi)

除了以上三種常見(jiàn)的形態(tài),內(nèi)部類(lèi)還可以聲明在局部,比如方法體內(nèi)部:

class Outer{
    void show(){
        class InnerFunc(){
            void showMsg(){}
        }
        new InnerFunc().showMsg();
    }
}

public class Test {
    public static void main(String[] str) {
        new Outer().show(); // 這樣就可以調(diào)用定義在方法內(nèi)部的類(lèi)了
    }
}

但是這種形式在日常開(kāi)發(fā)中使用并不多,至少我沒(méi)有用過(guò)。說(shuō)到這里,感覺(jué)這個(gè)有點(diǎn)類(lèi)似于python的在方法中聲明方法:

def outerFunc():
    def innerFunc():
        return "this is innerFunc"
    return innerFunc

內(nèi)部類(lèi)總結(jié)大概就要結(jié)束啦,以后想到再補(bǔ)充。

以上。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容