淺談Java面向?qū)ο笾畠?nèi)部類(lèi)
內(nèi)部類(lèi)是定義在另一個(gè)類(lèi)中的類(lèi),例如 TalkingClock 類(lèi)中內(nèi)嵌了 TimePrinter 類(lèi):
class TalkingClock{ private int interval; private boolean beep; public TalkingClock(int interval, boolean beep){} public void start(){} public class TimePrinter implements ActionListener{ public void actionPerformed(ActionEvent event){} }}
內(nèi)部類(lèi)可以對(duì)同一個(gè)包中的其他類(lèi)隱藏細(xì)節(jié),同時(shí)內(nèi)部類(lèi)中的方法可以訪問(wèn)原來(lái)的類(lèi)中的作用域數(shù)據(jù)。
訪問(wèn)外部對(duì)象內(nèi)部類(lèi)可以訪問(wèn)自身的數(shù)據(jù)字段,也可以訪問(wèn)創(chuàng)建它的外圍類(lèi)對(duì)象的數(shù)據(jù)字段。內(nèi)部類(lèi)會(huì)有一個(gè)隱式引用,指向創(chuàng)建它的外部類(lèi)對(duì)象。

對(duì)外圍類(lèi)的引用在構(gòu)造器中設(shè)置,編譯器會(huì)修改所有內(nèi)部類(lèi)的構(gòu)造器,添加一個(gè)對(duì)外部類(lèi)引用的參數(shù)。使用外部類(lèi)引用的語(yǔ)法為:
OuterClass.this
例如內(nèi)部類(lèi) TimePrinter 引用外部類(lèi) TalkingClock 的 beep 參數(shù),嚴(yán)格來(lái)說(shuō)要寫(xiě)成這樣。
TalkingClock.this.beep訪問(wèn)內(nèi)部對(duì)象
使用內(nèi)部類(lèi)的構(gòu)造器時(shí),可以使用下面的語(yǔ)法來(lái)實(shí)現(xiàn):
outerObject.new InnerClass(construction parameters)
在外部類(lèi)的作用域之外,想要引用內(nèi)部類(lèi)就需要用下面的語(yǔ)法:
OuterClass.InnerClass局部?jī)?nèi)部類(lèi)
局部?jī)?nèi)部類(lèi)類(lèi)似方法的局部變量,在類(lèi)外或者類(lèi)的其他方法中不能訪問(wèn)這個(gè)內(nèi)部類(lèi)。通常情況下可以在某個(gè)方法中局部實(shí)現(xiàn)一個(gè)類(lèi),這個(gè)類(lèi)將用于輔助該方法的功能實(shí)現(xiàn)。例如:
public void start(){ class TimePrinter implements ActionListener{ public void actionPerformed(ActionEvent event){ System.out.println('The time is ' + Instant.ofEpochMilli(event.getWhen())); if (beep) {Toolkit.getDefaultToolkit().beep(); } } } TimePrinter listener = new TimePrinter(); TalkingClock timer = new Timer(interval, listener); timer.start();}
聲明局部類(lèi)時(shí)不能有訪問(wèn)說(shuō)明符,局部類(lèi)的作用域被限定在了這個(gè)局部類(lèi)塊中。局部類(lèi)可以做到對(duì)外界的絕對(duì)隱藏,這是個(gè)很大的優(yōu)勢(shì)。局部類(lèi)還有個(gè)優(yōu)點(diǎn),就是可以訪問(wèn)局部變量。當(dāng)局部變量傳參進(jìn)來(lái)時(shí),局部變量也會(huì)被傳入構(gòu)造器,此時(shí)編譯器會(huì)為局部變量提供相應(yīng)的實(shí)例字段,保存一個(gè)副本。這么做的好處是,當(dāng)函數(shù)調(diào)用結(jié)束導(dǎo)致局部變量消失時(shí),局部類(lèi)還能夠使用這個(gè)局部變量。例如將上述的 start 方法改為傳入 2 個(gè)參數(shù),仍然不影響正常使用。
public void start(int interval, boolean beep)匿名內(nèi)部類(lèi)
使用局部類(lèi)時(shí),如果只是想建立這個(gè)局部類(lèi)的一個(gè)對(duì)象,甚至不需要給出這個(gè)類(lèi)的名字,這種類(lèi)就成為匿名內(nèi)部類(lèi)。匿名內(nèi)部類(lèi)的語(yǔ)法為:
new SuperType(construction parameters){ inner class methods and data} new InterfaceType(){ methods and data}
SuperType 指的是超類(lèi),此時(shí)局部類(lèi)就需要拓展這個(gè)類(lèi)。匿名局部類(lèi)可以基于接口創(chuàng)建,此時(shí)局部類(lèi)就要實(shí)現(xiàn)這個(gè)接口。由于構(gòu)造器的名字必須和類(lèi)名相同,而匿名局部類(lèi)沒(méi)有類(lèi)名,因此匿名局部類(lèi)不能有構(gòu)造器,此時(shí)如果要構(gòu)造參數(shù)就需要傳遞給超類(lèi)的構(gòu)造器。例如將上述的局部類(lèi)改造成匿名內(nèi)部類(lèi):
public void start(){ var listener = new ActionListener(){ public void actionPerformed(ActionEvent event){ System.out.println('The time is ' + Instant.ofEpochMilli(event.getWhen())); if (beep) {Toolkit.getDefaultToolkit().beep(); } } } TalkingClock timer = new Timer(interval, listener); timer.start();} 靜態(tài)內(nèi)部類(lèi)
有時(shí)候使用內(nèi)部類(lèi)只是想隱藏一個(gè)類(lèi),并不需要內(nèi)部類(lèi)有外部類(lèi)的引用,因此可以用 static 關(guān)鍵字聲明靜態(tài)內(nèi)部類(lèi)。例如定義 ArrayAlg 類(lèi)中實(shí)現(xiàn) minmax 方法,minmax 方法的功能是同時(shí)返回一個(gè)數(shù)組的最大值和最小值,但是用 return 只能返回一個(gè)值。因此可以定義一個(gè)靜態(tài)內(nèi)部類(lèi) Pair,Pair 類(lèi)有兩個(gè)參數(shù)可以分別存儲(chǔ)最大和最小值,這樣就可以通過(guò)返回 Pair 方法同時(shí)返回 2 個(gè)值了。
class ArrayAlg{ public static class Pair{ private double first; private double second; public Pair(double f, double s){ first = f; second = s; } public double getFirst() { return first; } public double getSecond() { return second; } } public static Pair minmax(double[] values){ double min = Double.POSITIVE_INFINITY; double max = Double.NEGATIVE_INFINITY; for (double v : values){ if (min > v) min = v; if (max < v) max = v; } return new Pair(min, max); }}
只要內(nèi)部類(lèi)不需要訪問(wèn)外圍類(lèi)對(duì)象,就應(yīng)該聲明為靜態(tài)內(nèi)部類(lèi)。和其他內(nèi)部類(lèi)不同,靜態(tài)內(nèi)部類(lèi)可以有靜態(tài)字段和方法。
以上就是淺談Java面向?qū)ο笾畠?nèi)部類(lèi)的詳細(xì)內(nèi)容,更多關(guān)于Java面向?qū)ο髢?nèi)部類(lèi)的資料請(qǐng)關(guān)注好吧啦網(wǎng)其它相關(guān)文章!
相關(guān)文章:
1. django queryset相加和篩選教程2. 利用ajax+php實(shí)現(xiàn)商品價(jià)格計(jì)算3. Java實(shí)現(xiàn)的迷宮游戲4. idea設(shè)置提示不區(qū)分大小寫(xiě)的方法5. JS圖片懶加載庫(kù)VueLazyLoad詳解6. Java利用TCP協(xié)議實(shí)現(xiàn)客戶(hù)端與服務(wù)器通信(附通信源碼)7. 使用AJAX(包含正則表達(dá)式)驗(yàn)證用戶(hù)登錄的步驟8. Java PreparedStatement用法詳解9. Spring如何集成ibatis項(xiàng)目并實(shí)現(xiàn)dao層基類(lèi)封裝10. IDEA 2020.1.2 安裝教程附破解教程詳解

網(wǎng)公網(wǎng)安備