匿名內部類

1、 內部類特性html

  1.  內部類仍然是一個獨立的類,在編譯以後內部類會被編譯成獨立的.class文件,可是前面冠之外部類的類名和$符號 。
  2.  內部類不能用普通的方式訪問。內部類是外部類的一個成員,所以內部類能夠自由地訪問外部類的成員變量,不管是不是private的 。
  3.  內部類聲明成靜態的,就不能隨便的訪問外部類的成員變量了,此時內部類只能訪問外部類的靜態成員變量 。

2、 匿名內部類app

1. ide

 

 1 public class Parcel7
 2 {
 3     public Contents contents()
 4     {
 5         return new Contents()  6         {
 7             private int i = 11;
 8             public int value() { return i; }
 9         }; 10     }
11     public static void main(String[] args)
12     {
13         Parcel7 p = new Parcel7();
14         Contents c = p.contents();
15     }
16 }

 

在上述代碼中, contents() 方法將返回值的生成與表達這個返回值的類定義結合在一塊兒。另外,這個類是匿名的,它沒有名字。spa

語法:建立一個繼承自Contents的匿名類的對象。經過new表達式返回的引用被自動向上轉型爲對Contents的引用。(向上轉型內容參照:http://www.javashuo.com/article/p-wpymcfzm-nw.htmlcode

關於分號的說明:在匿名內部類末尾的分號,並非用來標記此內部類結束的。實際上,它標記的是表達式的結束,只不過這個表達式正巧包含了匿名內部類,所以,這與別的地方使用的分號是一致的。htm

上述匿名內部類的代碼,是下面代碼的簡化版本:對象

 1 public class Parcel7
 2 {
 3     public MyContents implements contents
 4     {
 5         private int i = 11;
 6         public int value() { return i; }
 7     }
 8     public Contents contents() { return new MyContents(); }
 9     public static void main(String[] args)
10     {
11         Parcel7 p = new Parcel7();
12         Contents c = p.contents();
13     }
14 }

在這個匿名類中,使用了默認的構造器來生成Contents。blog

 

2. 下面代碼展現了基類須要一個有參數的構造器繼承

 1 public class Wrapping
 2 {
 3     private int i;
 4     public Wrapping(int x) { i = x; }
 5     public int value() { return i; }
 6 }
 7 //////////////////////////////////////////
 8 public class Parcel8
 9 {
10     public Wrapping wrapping(int x)
11     {
12         return new Wrapping(x)
13         {
14             public int value()
15             { 
16                 return super.value() * 47; 
17             }
18         };
19     }
20     public static void main(String[] args)
21     {
22         Parcel8 p = new Parcel8();
23         Contents w = p.wrapping();
24     }
25 }

在該例子中,能夠看到Wrapping擁有一個要求傳遞參數的構造器。接口

這裏是將x傳進new Warpping(x)。

在匿名內部類中,只須要簡單地傳遞合適的參數給基類的構造器便可。

 

3. 在匿名內部類定義中,對其進行初始化操做

 1 public class Parcel9
 2 {
 3     public Destination destination(final String dest)
 4     {
 5         return new Destination()
 6         {
 7             private String lable = dest;
 8             public String readLable() { return lable; }
 9         };
10     }
11     public static void main(String[] args)
12     {
13         Parcel9 p = new Parcel9();
14         Destination d = p.destination("Tasmaina");
15     }
16 }

在new Destination()中,使用到了在其外部定義的變量dest,編譯器要求咱們引用的參數是final的

即: 若是定義一個匿名內部類,而且但願他使用一個在其外部定義的對象,那麼編譯器會要求其參數引用final的。

 

4. 

若是隻是簡單的給一個字段賦值,那麼3例中的方法是很好的。可是,若是想作一個相似構造器的行爲,可是匿名類中不可能有命名構造器(其緣由是由於它根本就沒有名字)。經過實例初始化,就可以達到爲匿名內部類建立一個構造器的效果。具體實例以下:

 1 abstract class Base
 2 {
 3     public Base(int i)
 4     {
 5         System.out.println("Base coustructor. i = " + i);
 6     }
 7     public abstract void f();
 8 }
 9 public class AnonymousConstructor
10 {
11     public static Base getBase(int i)
12     {
13         return new Base(i)
14         {
15             { System.out.println("Inside instance initializer "); }
16             public void f()
17             {
18                 System.out.println("In anonymous f()");
19             }
20         };
21     }
22         public static void main(String[] args)
23         {
24             Base base = getBase(47);
25             base.f();
26         }
27 }

注意: 在此例中,並無要求變量 i 必定是final的,由於 i 被傳遞給匿名類的基類的構造器,並無在匿名類內部被直接使用。

 

5. 下面代碼爲帶實例初始化的形式

 1 public class Parcel10
 2 {
 3     public Destination destination(final String dest, final float price) 
 4     {
 5         return new Destination()
 6         {
 7             private int cost;
 8             {
 9                 cost = Math.round(price);
10                 if(cost > 100)
11                     System.out.println("Over budget");
12             }
13             private String lable = dest;
14             public String readLable() { return lable; }
15         };
16     }
17     public static void main(String[] args)
18     {
19         Parcel10 p = new Parcel10();
20         Destination d = p.destination("Tasmaina", 101.395F);
21     }
22 }

其中 destination 的參數必須是 final 的,由於他們在匿名類中被使用到了。

在實例初始化的內部,有 if 語句,它們不能做爲實例初始化動做的一部分。因此對於匿名類而言,實例初始化的實際效果就是構造器。(可是,你不能重載實例初始化方法,因此僅有一個這樣的構造器)

 

匿名內部類與正規繼承相比是受到限制的,由於匿名內部類既能夠擴展類,也能夠實現接口,可是不能兩者兼備。而且,若是是實現接口,也只能實現一個接口。

相關文章
相關標籤/搜索