Java匿名內(nèi)部類原理與用法詳解
本文實(shí)例講述了Java匿名內(nèi)部類原理與用法。分享給大家供大家參考,具體如下:
一 點(diǎn)睛
匿名內(nèi)部類適合創(chuàng)建那種只需要一次使用的類,定義匿名內(nèi)部類的語(yǔ)法格式如下:
new 父類構(gòu)造器(實(shí)參列表) | 實(shí)現(xiàn)接口()
{
//匿名內(nèi)部類的類體部分
}
從上面的定義可以看出,匿名內(nèi)部類必須繼承一個(gè)父類,或?qū)崿F(xiàn)一個(gè)接口,但最多只能繼承一個(gè)父類,或?qū)崿F(xiàn)一個(gè)接口。
兩條規(guī)則。
- 匿名內(nèi)部類不能是抽象類。
- 匿名內(nèi)部類不能定義構(gòu)造器。由于匿名內(nèi)部類沒(méi)有類名,所以無(wú)法定義構(gòu)造器,但匿名內(nèi)部類可以初始化塊,可以通過(guò)初始化塊來(lái)完成構(gòu)造器需要完成的工作。
二 實(shí)戰(zhàn)
1 點(diǎn)睛
最常用的創(chuàng)建匿名內(nèi)部類的方式是創(chuàng)建某個(gè)接口類型的對(duì)象。
2 代碼
interface Product
{
public double getPrice();
public String getName();
}
public class AnonymousTest
{
public void test(Product p)
{
System.out.println("購(gòu)買了一個(gè)" + p.getName()
+ ",花掉了" + p.getPrice());
}
public static void main(String[] args)
{
AnonymousTest ta = new AnonymousTest();
// 調(diào)用test()方法時(shí),需要傳入一個(gè)Product參數(shù),
// 此處傳入其匿名內(nèi)部類的實(shí)例
ta.test(new Product()
{
public double getPrice()
{
return 567.8;
}
public String getName()
{
return "AGP顯卡";
}
});
}
}
3 運(yùn)行
購(gòu)買了一個(gè)AGP顯卡,花掉了567.8
4 說(shuō)明
定義匿名內(nèi)部類無(wú)須class關(guān)鍵字,而是在定義匿名內(nèi)部類時(shí)直接生成該匿名內(nèi)部類的對(duì)象。
由于匿名內(nèi)部類不能是抽象類,所以匿名內(nèi)部類必須實(shí)現(xiàn)它的抽象父類或接口里包含的所有抽象方法。
三 實(shí)戰(zhàn)
1 點(diǎn)睛
當(dāng)通過(guò)接口來(lái)創(chuàng)建匿名內(nèi)部類時(shí),匿名內(nèi)部類不能顯示創(chuàng)建構(gòu)造器,因此匿名內(nèi)部類里只有一個(gè)隱式的無(wú)參構(gòu)造器,故new接口名后的括號(hào)里不能傳入?yún)?shù)值。
如果通過(guò)繼承父類來(lái)創(chuàng)建匿名內(nèi)部類時(shí),匿名內(nèi)部類將擁有和父類相似的構(gòu)造器,此處的相似指的是擁有相同的形參列表。
2 代碼
abstract class Device
{
private String name;
public abstract double getPrice();
public Device(){}
public Device(String name)
{
this.name = name;
}
// 此處省略了name的setter和getter方法
public void setName(String name)
{
this.name = name;
}
public String getName()
{
return this.name;
}
}
public class AnonymousInner
{
public void test(Device d)
{
System.out.println("購(gòu)買了一個(gè)" + d.getName()
+ ",花掉了" + d.getPrice());
}
public static void main(String[] args)
{
AnonymousInner ai = new AnonymousInner();
// 調(diào)用有參數(shù)的構(gòu)造器創(chuàng)建Device匿名實(shí)現(xiàn)類的對(duì)象
ai.test(new Device("電子示波器")
{
public double getPrice()
{
return 67.8;
}
});
// 調(diào)用無(wú)參數(shù)的構(gòu)造器創(chuàng)建Device匿名實(shí)現(xiàn)類的對(duì)象
Device d = new Device()
{
// 初始化塊
{
System.out.println("匿名內(nèi)部類的初始化塊...");
}
// 實(shí)現(xiàn)抽象方法
public double getPrice()
{
return 56.2;
}
// 重寫父類的實(shí)例方法
public String getName()
{
return "鍵盤";
}
};
ai.test(d);
}
}
3 運(yùn)行
購(gòu)買了一個(gè)電子示波器,花掉了67.8
匿名內(nèi)部類的初始化塊...
購(gòu)買了一個(gè)鍵盤,花掉了56.2
當(dāng)創(chuàng)建以Device為父類的匿名內(nèi)部類時(shí),既可以傳入?yún)?shù),代表調(diào)用父類帶參數(shù)的構(gòu)造器;也可以不傳入?yún)?shù),代表調(diào)用父類無(wú)參數(shù)的構(gòu)造器。
當(dāng)創(chuàng)建匿名內(nèi)部類時(shí),必須實(shí)現(xiàn)接口或抽象父類里的所有抽象方法。如果有需要,也可以重寫父類中的普通方法。
四 實(shí)戰(zhàn)
1 點(diǎn)睛
在Java 8之前,Java要求被局部?jī)?nèi)部類、匿名內(nèi)部類訪問(wèn)的局部變量必須使用final修飾,從Java 8開始這個(gè)限制取消了,Java 8更加智能:如果局部變量被匿名內(nèi)部類訪問(wèn),那么該局部變量相對(duì)于自動(dòng)使用了final修飾。
2 代碼
interface A
{
void test();
}
public class ATest
{
public static void main(String[] args)
{
int age = 8; // ①
// 下面代碼將會(huì)導(dǎo)致編譯錯(cuò)誤
// 由于age局部變量被匿名內(nèi)部類訪問(wèn)了,因此age相當(dāng)于被final修飾了
//age = 2;
A a = new A()
{
public void test()
{
// 在Java 8以前下面語(yǔ)句將提示錯(cuò)誤:age必須使用final修飾
// 從Java 8開始,匿名內(nèi)部類、局部?jī)?nèi)部類允許訪問(wèn)非final的局部變量
System.out.println(age);
}
};
a.test();
}
}
3 結(jié)果
8
4 說(shuō)明
Java 8將這個(gè)功能稱為“effectively final”,它的意思是對(duì)于被匿名內(nèi)部類訪問(wèn)的局部變量,可以用final修飾,也可以不用final修飾,但必須按照有final修飾的方式來(lái)使用——也就是一次賦值后,以后不能重新賦值。
更多java相關(guān)內(nèi)容感興趣的讀者可查看本站專題:《Java面向?qū)ο蟪绦蛟O(shè)計(jì)入門與進(jìn)階教程》、《Java數(shù)據(jù)結(jié)構(gòu)與算法教程》、《Java操作DOM節(jié)點(diǎn)技巧總結(jié)》、《Java文件與目錄操作技巧匯總》和《Java緩存操作技巧匯總》
希望本文所述對(duì)大家java程序設(shè)計(jì)有所幫助。
相關(guān)文章
java GUI編程之監(jiān)聽(tīng)操作實(shí)例分析
這篇文章主要介紹了java GUI編程之監(jiān)聽(tīng)操作,結(jié)合實(shí)例形式分析了java GUI編程監(jiān)聽(tīng)操作的Button監(jiān)聽(tīng)、TextField文本輸入監(jiān)聽(tīng)等相關(guān)操作技巧與注意事項(xiàng),需要的朋友可以參考下2020-01-01
myBatis組件教程之緩存的實(shí)現(xiàn)與使用
這篇文章主要給大家介紹了關(guān)于myBatis組件教程之緩存的實(shí)現(xiàn)與使用的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2018-11-11
如何在MyBatis中實(shí)現(xiàn)DataSource
今天給大家整理了如何在MyBatis中實(shí)現(xiàn)DataSource,文中有非常詳細(xì)的代碼示例,對(duì)正在學(xué)習(xí)java的小伙伴們很有幫助,需要的朋友可以參考下2021-06-06
SpringBoot去除參數(shù)前后空格和XSS過(guò)濾
本文主要介紹了SpringBoot去除參數(shù)前后空格和XSS過(guò)濾,文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-09-09
java-流的使用完結(jié)與異常處理機(jī)制(詳解)
下面小編就為大家?guī)?lái)一篇java-流的使用完結(jié)與異常處理機(jī)制(詳解)。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-09-09
java將html轉(zhuǎn)成圖片代碼實(shí)例(html2image)
這篇文章主要介紹了java將html轉(zhuǎn)成圖片的相關(guān)資料,在Java開發(fā)中,將HTML轉(zhuǎn)換為圖片可以使用html2image庫(kù),文中通過(guò)代碼及圖文介紹的非常詳細(xì),需要的朋友可以參考下2024-09-09
mybatis調(diào)用mysql存儲(chǔ)過(guò)程(返回參數(shù),單結(jié)果集,多結(jié)果集)
本文主要介紹了mybatis調(diào)用mysql存儲(chǔ)過(guò)程(返回參數(shù),單結(jié)果集,多結(jié)果集),文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-01-01

