解析java匿名内部类
Java 8 改進(jìn)的匿名內(nèi)部類
適用范圍:
匿名內(nèi)部類適合于方便程序?qū)崿F(xiàn)接口,即匿名內(nèi)部類相當(dāng)于接口的實(shí)現(xiàn)類。
創(chuàng)建原理:
創(chuàng)建匿名內(nèi)部類在實(shí)現(xiàn)接口的時(shí)候會(huì)立即創(chuàng)建一個(gè)沒有名字類的實(shí)例用來實(shí)現(xiàn)某一接口,這個(gè)類立即創(chuàng)建立即消失,匿名內(nèi)部類不能重復(fù)使用
(匿名內(nèi)部類中有一個(gè)隱式的無參構(gòu)造器)
定義匿名內(nèi)部類的格式如下:
new 實(shí)現(xiàn)接口 ( ) | 父類構(gòu)造器 ( 實(shí)參列表 )
{
//匿名內(nèi)部類的實(shí)體部分
}
關(guān)于匿名內(nèi)部類還有如下規(guī)則:
最常見的創(chuàng)建匿名內(nèi)部類的方式是需要?jiǎng)?chuàng)建某個(gè)接口類型的對(duì)象,如下程序所示:
//定義一個(gè)產(chǎn)品的接口 interface Product{double getPrice();String getName();} public class AnonymousTest {//定義一個(gè)方法實(shí)現(xiàn)“買”這種行為;public void test (Product p){System.out.println("購(gòu)買了一個(gè)"+p.getName()+",花掉了"+p.getPrice());};public static void main(String[] args) {AnonymousTest at=new AnonymousTest();//調(diào)用test()方法時(shí),需要傳遞一個(gè)參數(shù)//此處通過匿名內(nèi)部類實(shí)現(xiàn)at.test(new Product() {@Overridepublic double getPrice() {return 57.8;}@Overridepublic String getName() {return "APG顯卡";}});}}上面程序中的AnonymousTest定義了一個(gè)test( ) 方法,該方法需要一個(gè) Product對(duì)象作為參數(shù),但Product只是一個(gè)接口,無法直接創(chuàng)建對(duì)象,因此此處考慮創(chuàng)建一個(gè)Product接口實(shí)現(xiàn)類的對(duì)象傳入該方法(即匿名內(nèi)部類)
如果這個(gè)Prodect接口實(shí)現(xiàn)類需要重復(fù)使用,則應(yīng)該將該實(shí)現(xiàn)類定義成一個(gè)獨(dú)立類;如果這個(gè)Product接口實(shí)現(xiàn)類只需使用一次,則可采用上面程序中的方式,定義一個(gè)匿名內(nèi)部類。
//如果需要重復(fù)使用Product接口,那么將實(shí)現(xiàn)類定義為獨(dú)立類;
定義匿名內(nèi)部類無須 class 關(guān)鍵字,而是在定義匿名內(nèi)部類時(shí)直接生成該匿名內(nèi)部類的對(duì)象。由于匿名內(nèi)部類不能是抽象類(抽象類不能實(shí)例化),所以匿名內(nèi)部類必須實(shí)現(xiàn)它的抽象父類或者接口里包含的所有抽象方法,
下面是對(duì)于上面代碼的另外一種實(shí)現(xiàn)方式(接口需要重復(fù)使用,則將實(shí)現(xiàn)類定義為一個(gè)獨(dú)立類):
class implementsClass implements Product{@Overridepublic double getPrice() {return 57.8;}@Overridepublic String getName() {return "AGP顯卡";}at.text(new implementsClass());上面兩段代碼功能完全一樣,只不過采用匿名內(nèi)部類的寫法更加簡(jiǎn)潔。
當(dāng)通過實(shí)現(xiàn)接口來創(chuàng)建匿名內(nèi)部類時(shí),匿名內(nèi)部類也不能顯式創(chuàng)建構(gòu)造器,因此**匿名內(nèi)部類只有一個(gè)隱式的無參數(shù)構(gòu)造器,**故 new 接口后的括號(hào)里不能穿入?yún)?shù)。但如果通過繼承父類來創(chuàng)建匿名內(nèi)部類時(shí),匿名內(nèi)部類講擁有和父類相似的構(gòu)造器,此處的相似是指擁有相同的形成列表。(當(dāng)匿名內(nèi)部類用來實(shí)現(xiàn)抽象類的時(shí)候可以將抽象類看作是匿名類內(nèi)部類的父類,即匿名內(nèi)部類會(huì)繼承抽象類的所有的方法,也可以使用抽象類中的構(gòu)造器)
看下面的程序:
//定義一個(gè)抽象類 abstract class Device {private String name;public abstract double getPrice();public Device(){};public Device(String name){this.name=name;}public String getName() {return name;}public void setName(String name) {this.name = 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)造器來實(shí)現(xiàn)匿名內(nèi)部類ai.test(new Device("電子示波器") {@Overridepublic double getPrice() {return 67.8;}});//調(diào)用無參數(shù)的的構(gòu)造器創(chuàng)建匿名內(nèi)部類Device d=new Device() {//初始化代碼塊{System.out.println("匿名內(nèi)部類初始化代碼塊……");}@Overridepublic double getPrice() {return 56.3;}//重寫父類的實(shí)例方法public String getName(){return "鍵盤";}};ai.test(d);}}上面程序創(chuàng)建了一個(gè)抽象父類Devite 類,這個(gè)抽象父類里面包含兩個(gè)構(gòu)造器:一個(gè)無參數(shù)的,一個(gè)有參數(shù)的。當(dāng)創(chuàng)建以 Devite為父類的匿名內(nèi)部類時(shí),既可以傳入?yún)?shù),代表調(diào)用父類帶參數(shù)的構(gòu)造器;也可以不傳入?yún)?shù),代表調(diào)用父類無參數(shù)的構(gòu)造器。當(dāng)創(chuàng)建匿名內(nèi)部類時(shí),必須實(shí)現(xiàn)接口或抽象父類里的所有抽象方法。如果有需要,也可以重寫父類中的普通方法。如上面程序中,匿名內(nèi)部類重寫了抽象父類Devite類的 getName ( ) 方法,其中 getName ( ) 方法并不是抽象方法。
在 Java 8 之前,Java 要求被局部?jī)?nèi)部類、匿名內(nèi)部類訪問的局部變量必須使用 final 修飾,從 Java 8 開始這個(gè)限制被取消了,Java 8 更加智能:如果局部變量被匿名內(nèi)部類訪問,那么該局部變量相當(dāng)于自動(dòng)使用了 final 修飾。
interface Student {void getAge();}public class InnerDemo {public static void main(String [] args){int age=10; //1??Student student=new Student() {@Overridepublic void getAge() {//在 Java 8 以前下面語句將提示錯(cuò)誤,age 必須使用 final 修飾//從 java 8 開始,匿名內(nèi)部類、局部?jī)?nèi)部類允許訪問非 final 的局部變量System.out.println(age);}};student.getAge();} }Java 8 將這種功能稱為“ effectivity final ” ,它的意思是對(duì)于被匿名內(nèi)部類訪問的局部變量,可以用 final 修飾,也可以不用 final 修飾,但必須按照油final 修飾的方式來用——也就是一次賦值后,以后不能重新賦值。如上面程序如果在1??代碼后添加如下代碼:age=20;將會(huì)導(dǎo)致編譯錯(cuò)誤。(即java8以后被匿名內(nèi)部類訪問的局部變量相當(dāng)于自動(dòng)加上了final修飾符,不可以對(duì)該局部變量就行二次賦值)
《新程序員》:云原生和全面數(shù)字化實(shí)踐50位技術(shù)專家共同創(chuàng)作,文字、視頻、音頻交互閱讀總結(jié)
以上是生活随笔為你收集整理的解析java匿名内部类的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 平面设计师如何训练自己创意思维
- 下一篇: 线程生命周期的理解