全面探究 Java 內(nèi)部類
內(nèi)部類(inner class)是定義在另一個(gè)類中的類。為什么要使用內(nèi)部類呢?主要有兩個(gè)原因:1.內(nèi)部類可以對(duì)同一個(gè)包中的其他類隱藏。2.內(nèi)部類方法可以訪問定義這個(gè)類的作用域中的數(shù)據(jù),包括原本私有的數(shù)據(jù)。
下面,我就來帶領(lǐng)大家去學(xué)習(xí)Java中比較常見的幾種內(nèi)部類,希望對(duì)大家有一定的收獲!
一. 實(shí)例內(nèi)部類
1. 定義
什么是實(shí)例內(nèi)部類呢?顧名思義,就是在一個(gè)普通類的內(nèi)部再定義一個(gè)類,即為實(shí)例內(nèi)部類。
如:
class OuterClass{ public int data1=1; public static int data2=2; class InnerClass{ public int data3=3; } }
但是應(yīng)該注意實(shí)例內(nèi)部類里不能有static修飾的靜態(tài)成員變量,我們可以把實(shí)例內(nèi)部類當(dāng)做類中的一個(gè)實(shí)例成員,那么當(dāng)我們調(diào)用它的時(shí)候,可以認(rèn)為調(diào)用的過程是依賴于對(duì)象的,但是static又不依賴于對(duì)象,因此我們可以推出不能有static修飾的字段。如果非要使用靜態(tài)的,那么必須再加上final,即用static final
來修飾,因?yàn)橛胒inal修飾后的值是無法更改的,可以把它當(dāng)做是一個(gè)常量,即在編譯期間可以確定它的值,這樣就不會(huì)報(bào)錯(cuò)了
2. 如何獲取實(shí)例內(nèi)部類這個(gè)對(duì)象的引用
在創(chuàng)建好一個(gè)內(nèi)部類后,我們?cè)撊绾卧L問內(nèi)部類里的成員屬性呢?一般通過new 兩次對(duì)象來獲?。?/p>
OuterClass outerClass = new OuterClass(); OuterClass.InnerClass innerClass = outerClass.new InnerClass();
當(dāng)然我們也可以通過匿名對(duì)象的方法直接獲?。?/p>
OuterClass.InnerClass innerClass2 = new OuterClass().new InnerClass();
此處的語(yǔ)法還是比較繞的如果實(shí)在理解不了的話直接記住就行~
3. 注意事項(xiàng)
當(dāng)實(shí)例內(nèi)部類中與外部類有同名的成員變量時(shí),通過實(shí)例內(nèi)部類去訪問這個(gè)成員變量會(huì)訪問實(shí)例內(nèi)部類自己的,例如:
class OuterClass{ public int data1=1; public static int data2=2; class InnerClass{ public int data1=10; } } public class TestDemo { public static void main(String[] args) { OuterClass outerClass = new OuterClass(); OuterClass.InnerClass innerClass = outerClass.new InnerClass(); System.out.println(innerClass.data1); } }
運(yùn)行結(jié)果為:
那么我們?nèi)绾瓮ㄟ^實(shí)例內(nèi)部類的引用去訪問外部類中的data1呢?方法如下:
class OuterClass{ public int data1=1; public static int data2=2; class InnerClass{ public int data1=10; public void func(){ System.out.println(data1); System.out.println(this.data1);//this為自己的對(duì)象的引用 System.out.println(OuterClass.this.data1);//this為外部類對(duì)象的引用 } } } public class TestDemo { public static void main(String[] args) { OuterClass outerClass = new OuterClass(); OuterClass.InnerClass innerClass = outerClass.new InnerClass(); innerClass.func(); } }
打印結(jié)果為:
二. 靜態(tài)內(nèi)部類
1. 定義
和實(shí)例內(nèi)部類一樣,我們也可以把靜態(tài)內(nèi)部類當(dāng)做外部類的一個(gè)成員屬性,只不過是靜態(tài)的
代碼演示如下:
class OuterClass{ public int data1=1; public static int data2=2; static class InnerClass{ public int data1=10; public static int data2=20; public void func(){ System.out.println(data1); System.out.println(this.data1); System.out.println(OuterClass.this.data1); } } }
注意,靜態(tài)內(nèi)部類中可以定義靜態(tài)的成員屬性了
2. 如何獲取靜態(tài)內(nèi)部類這個(gè)對(duì)象的引用
和獲取實(shí)例內(nèi)部類對(duì)象引用的方法差不多,但稍有變動(dòng):OuterClass.InnerClass innerClass=new OuterClass.InnerClass();
3. 注意事項(xiàng)
同樣,我們也有一些需要注意的問題,在靜態(tài)內(nèi)部類當(dāng)中,我們不能訪問外部類的非靜態(tài)數(shù)據(jù)成員。
因?yàn)殪o態(tài)內(nèi)部類不依賴于對(duì)象,而外部類不是靜態(tài)的,是依賴于對(duì)象的,如果非要訪問,我們可以在內(nèi)部類中構(gòu)造一個(gè)外部類對(duì)象的引用out
代碼示例如下:
class OuterClass{ public int data1=1; public static int data2=2; static class InnerClass{ public int data1=10; public static int data2=20; public OuterClass out; public InnerClass(OuterClass o){ this.out=o; } public void func(){ System.out.println(data1); System.out.println(this.out.data1); } } } public class TestDemo { public static void main(String[] args) { OuterClass outerClass = new OuterClass(); OuterClass.InnerClass innerClass=new OuterClass.InnerClass(outerClass); innerClass.func(); }
打印結(jié)果為:
三. 匿名內(nèi)部類
1. 定義
匿名內(nèi)部類是一個(gè)用法較為簡(jiǎn)單的類,寫法示例如下:
class OuterClass{ public void func(){ System.out.println("匿名內(nèi)部類"); } } public class TestDemo{ public static void main(String[] args) { new OuterClass(){ //此處為匿名內(nèi)部類 }; } }
當(dāng)然,在匿名內(nèi)部類中也可以重寫外部類中的方法:
lass OuterClass{ public void func(){ System.out.println("匿名內(nèi)部類"); } } public class TestDemo{ public static void main(String[] args) { new OuterClass(){ @Override public void func() { System.out.println("此處為重寫后的func方法"); } }; } }
調(diào)用重寫后的方法步驟如下:
public static void main(String[] args) { new OuterClass(){ @Override public void func() { System.out.println("此處為重寫后的func方法"); } }.func(); }
打印結(jié)果:
注意,匿名內(nèi)部類只定義一次且沒有名字
2. 常見用法
interface A { public void func(); } A a = new A(){ @Override public void func() { System.out.println("當(dāng)前是個(gè)匿名內(nèi)部類,實(shí)現(xiàn)了A接口,重寫了接口的方法"); } };
上面部分的代碼為匿名內(nèi)部類,這個(gè)內(nèi)部類實(shí)現(xiàn)了A接口并且重寫了A接口中的方法
3. 注意事項(xiàng)
匿名內(nèi)部類中有一個(gè)變量捕獲機(jī)制,即匿名內(nèi)部類中變量的值是無法修改的
public static void main(String[] args) { int flag=1; new OuterClass(){ @Override public void func() { System.out.println("此處為重寫后的func方法"); System.out.println(flag); } }.func(); }
此時(shí)我們的程序可以正常運(yùn)行,打印的結(jié)果為1
然而,當(dāng)我們修改flag的值后,程序會(huì)報(bào)錯(cuò):
因此,需要牢記匿名內(nèi)部類中的變量捕獲機(jī)制,即無法二次修改變量的值?。?!
好啦,本期有關(guān)內(nèi)部類的分享就到此結(jié)束了,大家一起加油鴨!
到此這篇關(guān)于全面探究 Java 內(nèi)部類的文章就介紹到這了,更多相關(guān)Java 內(nèi)部類內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
基于swagger測(cè)試List類型參數(shù)過程詳解
這篇文章主要介紹了基于swagger測(cè)試List類型參數(shù)過程詳解,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-09-09使用IDEA如何導(dǎo)入SpringBoot項(xiàng)目
這篇文章主要介紹了使用IDEA如何導(dǎo)入SpringBoot項(xiàng)目問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,2023-12-12Mybatis-Plus開發(fā)提速器mybatis-plus-generator-ui詳解
這篇文章主要介紹了Mybatis-Plus開發(fā)提速器mybatis-plus-generator-ui,本文簡(jiǎn)要介紹一款基于Mybatis-Plus的代碼自助生成器,文章通過實(shí)例集成的方式來詳細(xì)講解mybatis-plus-generator-ui,從相關(guān)概念到實(shí)際集成案例,以及具體的擴(kuò)展開發(fā)介紹,需要的朋友可以參考下2022-11-11使用String類型小數(shù)值轉(zhuǎn)換為L(zhǎng)ong類型
這篇文章主要介紹了使用String類型小數(shù)值轉(zhuǎn)換為L(zhǎng)ong類型操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-09-09