java匿名內部類

轉自 流年飛舞      http://blog.sina.com.cn/s/blog_62ea4cf40100mubj.html


匿名類是不能有名稱的類,所以沒辦法引用它們。必須在創建時,作爲new語句的一部分來聲明它們。這就要採用另一種形式的new語句,如下所示: new <類或接口> <類的主體> 這種形式的new語句聲明一個新的匿名類,它對一個給定的類進行擴展,或者實現一個給定的接口。它還創建那個類的一個新實例,並把它作爲語句的結果而返回。要擴展的類和要實現的接口是new語句的操作數,後跟匿名類的主體。如果匿名類對另一個類進行擴展,它的主體可以訪問類的成員、覆蓋它的方法等等,這和其他任何標準的類都是一樣的。如果匿名類實現了一個接口,它的主體必須實現接口的方法。

interface pr  
{  
void print1();  
}  
                                    
public class noNameClass   
{  
public pr dest()  
{  
    return new pr(){  
     public void print1()  
     {  
      System.out.println("Hello world!!");  
     }  
    };  
}  
                                    
public static void main(String args[])  
{  
    noNameClass c=new     noNameClass();  
    pr hw=c.dest();  
    hw.print1();  
}  
}  

pr也可以是一個類但是你外部調用的方法必須在你的這個類或接口中聲明外部不能調用匿名類內部的方法

Java中內部匿名類用的最多的地方也許就是在Frame中加入Listner了吧。
如下:

import java.awt.*;  
import java.awt.event.*;  
                                
public class QFrame extends Frame {  
    public QFrame() {  
           this.setTitle(\"my application\");  
                                
           addWindowListener(new WindowAdapter() {  
                   public void windowClosing(WindowEvent e) {  
                   dispose();  
                   System.exit(0);  
}  
            });    
                                
          this.setBounds(10,10,200,200);  
     }  
}

內部匿名類,就是建立一個內部的類,但沒有給你命名,也就是沒有引用實例的變量。

new WindowAdapter() {
      public void windowClosing(WindowEvent e) {
             dispose();
             System.exit(0);
     }
}

new 是建立一個 WindowAdapter對象 ,後面一個 {} 表示這個括號中的操作作用於這個默認的對名象,而上面的Java程序中後面是一個函數體。
這個用法的作用是:創建一個對象的實例,並且 override 它的一個函數。打開 WindowAdapter 的代碼可以發現。它是一個抽象類。它是對 WindowListener 接口的一個實現。Frame.addWindowListner(); 的參數是一個 WindowListner ,而實現上是傳一個從WindowAdapter 派生出的一個匿名類。

1.怎樣判斷一個匿名類的存在啊?看不見名字,感覺只是父類new出一個對象而已,沒有匿名類的名字。

先看段僞代碼

abstract class Father(){
....
}
public class Test{
   Father f1 = new Father(){ .... }  //這裏就是有個匿名內部類
}

一般來說,new 一個對象時小括號後應該是分號,也就是new出對象該語句就結束了。
但是出現匿名內部類就不一樣,小括號後跟的是大括號,大括號中是該new 出對象的具體的實現方法。
因爲我們知道,一個抽象類是不能直接new 的,必須先有實現類了我們才能new出它的實現類。
上面的僞代碼就是表示new 的是Father的實現類,這個實現類是個匿名內部類。
其實拆分上面的匿名內部類可爲

class SonOne extends Father{
  ...       //這裏的代碼和上面匿名內部類,大括號中的代碼是一樣的
}
public class Test{
   Father f1 = new SonOne() ;
}

2.匿名內部類的注意事項

注意匿名類的聲明是在編譯時進行的,實例化在運行時進行。這意味着for循環中的一個new語句會創建相同匿名類的幾個實例,而不是創建幾個不同匿名類的一個實例。

在使用匿名內部類時,要記住以下幾個原則:
 ·匿名內部類不能有構造方法。
 ·匿名內部類不能定義任何靜態成員、方法和類。
 ·匿名內部類不能是public,protected,private,static。
 ·只能創建匿名內部類的一個實例。
·一個匿名內部類一定是在new的後面,用其隱含實現一個接口或實現一個類。
 ·因匿名內部類爲局部內部類,所以局部內部類的所有限制都對其生效。

·內部類只能訪問外部類的靜態變量或靜態方法。

匿名類和內部類中的中的this :
有時候,我們會用到一些內部類和匿名類。當在匿名類中用this時,這個this則指的是匿名類或內部類本身。這時如果我們要使用外部類的方法和變量的話,則應該加上外部類的類名

3.匿名內部類的作用

Java的內部類和C++中的嵌套類有本質的不同:C++的嵌套類沒有指向包裝類的句柄。僅僅表達一個封裝的概念;但是Java的內部類不同,它可以訪問包裝類的成員(這表示它擁有指向包裝類的句柄)。
匿名內部類是內部類的一種簡化寫法:return new Wrapper {
...
};
等價於:Wrapped extends Wrapper {
...
}
return new Wrapped();

難道匿名內部類就只這一點作用嗎?

考慮一下這樣的case:

interface ICount {
   int count();
 }
 class Parent {
   int i = 0;
   int count() {
     return i++;
   }
 }

有一個類Child,它既想繼承Parent的count()方法,又想實現ICount接口中的count方法,這個時候怎麼辦呢?內部類就可以大顯身手了:

class Child extends Parent {
    ICount getCount() {
      return new ICount {
        int i = 0;
        int count() {
         return (i *= 2);
        }
      }
    }
  }


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章