匿名內部類精講

來源:互聯網
上載者:User

匿名內部類適合建立那種只需要一次使用的類,例如命令模式時所需要的Command對象。匿名內部類的文法有點奇怪,建立匿名內部類時會立即建立一個該類的執行個體,這個類定義立即消失,匿名內部類不能重複使用。
    定義匿名內部類的格式如下:

new 父類構造器(參數列表)|實現介面()<br /> {<br /> //匿名內部類的類體部分<br /> } 

從上面定義可以看出,匿名內部類必須繼承一個父類,或實現一個介面,但最多隻能繼承一個父類,或實現一個介面。
 關於匿名內部類還有如下兩條規則:
 1)匿名內部類不能是抽象類別,因為系統在建立匿名內部類的時候,會立即建立內部類的對象。因此不允許將匿名內部類
 定義成抽象類別。
 2)匿名內部類不等定義構造器,因為匿名內部類沒有類名,所以無法定義構造器,但匿名內部類可以定義執行個體初始化塊,
 通過執行個體初始化塊來完成構造器需要完成的事情。
 最常用的建立匿名內部類的方式是需要建立某個介面類型的對象,如下程式所示: interface Product{<br /> public double getPrice();<br /> public String getName();<br /> }<br /> public class TestAnonymous{<br /> public void test(Product p){<br /> System.out.println("購買了一個"+p.getName()+",花掉 了"+p.getPrice());<br /> }<br /> public static void main(String[]args){<br /> TestAnonymous ta = new TestAnonymous();<br /> ta.test(new Product(){<br /> public double getPrice(){<br /> return 567;<br /> }<br /> public String getName(){<br /> return "AGP顯卡";<br /> }<br /> });<br /> }<br /> } 

上面程式中的TestAnonymous類定義了一個test方法,該方法需要一個Product對象作為參數,但Product只是一個介面,
無法直接建立對象,因此此處考慮建立一個Product介面實作類別的對象傳入該方法---如果這個Product介面實作類別需要重複
使用,則應該經該實作類別定義一個獨立類;如果這個Product介面實作類別只需一次使用,則可採用上面程式中的方式,定義
一個匿名內部類。
    正如上面程式中看到,定義匿名類不需要class關鍵字,而是在定義匿名內部類時直接產生該匿名內部類的對象。上面
粗體字代碼部分就是匿名類的類體部分。
 由於匿名內部類不能是抽象類別,所以匿名內部類必須實現它的抽象父類或者介面裡包含的所有抽象方法。
 對於上面建立Product實作類別對象的代碼,可以拆分成如下代碼:

class AnonymousProduct implements Product{<br /> public double getPrice(){<br /> return 567;<br /> }<br /> public String getName(){<br /> return "AGP顯卡";<br /> }<br /> }<br /> ta.test(new AnonymousProduct()); 

 當通過實現介面來建立匿名內部類時,匿名內部類也不能顯示建立構造器,因此匿名內部類只有一個隱式的無參數構造
器,故new介面名後的括弧裡不能傳入參數值。
    但如果通過繼承父類來建立匿名內部類是,匿名內部類將擁有和父類相似的構造器,此處的相似指的是擁有相同的形參
列表。

 

 

 

abstract class Device{<br /> private String name;<br /> public Device(){<br /> }<br /> public Device(String name){<br /> this.name = name;<br /> }<br /> public abstract double getPrice();<br /> //此處省略了name屬性的setter和getter方法<br /> }<br /> public class AnonymousInner{<br /> public void test(Device d){<br /> System.out.println("購買了一個"+d.getName()+",花掉了"+d.getPrice());<br /> }<br /> public static void main(String[] args){<br /> AnonymousInner ai = new AnonymousInner();<br /> //調用有參數的構造器建立Device匿名實作類別的對象<br /> ai.test(new Device("電子示波器"){<br /> public double getPrice(){<br /> return 67;<br /> }<br /> });<br /> //調用無參數的構造器建立Device匿名實作類別的對象<br /> Device d = new Device(){<br /> //初始化塊<br /> {<br /> System.out.println("匿名內部類的初始化塊...");<br /> }<br /> //實現抽象方法<br /> public double getPrice(){<br /> return 56;<br /> }<br /> public Sting getName(){<br /> return "鍵盤";<br /> }<br /> };<br /> ai.test(d);<br /> }<br /> } 

上面程式建立了一個抽象父類Device,這個抽象父類裡包含兩個構造器:一個無參數的,一個有參數的。當建立以Device
為父類的匿名內部類時,即可以傳入參數(如上面程式中第一段粗體字部分),也可以不傳入參數(如上面程式中第二段粗體
字部分)。
 當建立匿名內部類時,必須實現介面或抽象父類裡的所有抽象方法。如果有需要,也可以重寫父類中的普通方法,如上面
程式的第二段粗體字代碼部分,匿名內部類重寫了抽象父類Device類的getName方法,其中getName方法並不是抽象方法。
    如果匿名內部類需要訪問外部類的局部變數,則必須使用final修飾符來修飾外部類的局部變數,
否則系統將報錯。

interface A{<br /> void test();<br /> }<br /> public class TestA{<br /> public static void main(Strign[] args){<br /> int age = 0;<br /> A a = new A(){<br /> public void test(){<br /> //下面語句將提示錯誤:匿名內部類內訪問局部變數必須使用final修飾<br /> System.out.println(age);<br /> }<br /> };<br /> }<br /> } 

 上面程式中粗體子代碼是匿名內部類訪問了外部類的局部變數,由於age變數沒有使用final修飾符修飾,所以粗體字代碼將
引起編譯異常。


聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.