2012-12-04 122 views
0

我正在嘗試挖掘匿名類,並且剛剛出現了一個問題我不想引用太多細節並直接提出我的問題:如何調用方法sizzle()在以下匿名類:調用匿名類的子類方法

public class Popcorn { 
    public void pop() { 
     System.out.println("popcorn"); 
    } 
} 

class Food { 
    Popcorn p = new Popcorn() { 
     public void sizzle() { 
      System.out.println("anonymous sizzling popcorn"); 
     } 

     public void pop() { 
      System.out.println("anonymous popcorn"); 
     } 
    }; 

    public void popIt() { 
     p.pop(); // OK, Popcorn has a pop() method 
     p.sizzle(); // Not Legal! Popcorn does not have sizzle() 
    } 
} 

已知並且在一個超類的一個refernce不能調用子類的方法,而沒有向下轉換(即使它是指在給定的子類的一個對象)多態性的規則確定。但是,在上述情況下,調用sizzle()方法的「關鍵」是什麼?

+2

唯一的方法是在爆米花類中實施嘶嘶聲。 – PermGenError

+2

**使用一個命名的類** – millimoose

回答

2

sizzle()方法根本無法從外部訪問,因爲該類是匿名的。

p參考是一個類型Popcorn,並沒有定義sizzle()

匿名類的意思是一次性,而在一些設計模式(如觀察員)被大量使用,因爲Java沒有一流的功能,即不能傳遞函數對象周圍。

+0

「sizzle()'方法根本無法從外部訪問,因爲類是匿名的」這在技術上不是真實的。請參閱[我的答案](http://stackoverflow.com/a/13714930/41655)。 – millimoose

1

當您撥打p.sizzle()時,您需要將p變量設置爲具有sizzle()方法的類型。 唯一的方法是使用子類或接口。 你甚至可以施放,如果你不想改變p的類型,但是你不能轉換成匿名類型。

new Object() { 
    public void foo() {} 
}.foo(); 

如果你需要一個類只有Food類裏面,你應該在那裏

class Food { 
    EdiblePopcorn p = new EdiblePopcorn() { 

     @Override 
     public void sizzle() { 
      System.out.println("anonymous sizzling popcorn"); 
     } 

     @Override 
     public void pop() { 
      System.out.println("anonymous popcorn"); 
     } 
    }; 

    public void popIt() { 
     p.pop(); // OK, Popcorn has a pop() method 
     p.sizzle(); // Also legal! EdiblePopcorn now has sizzle() 
    } 

    private abstract class EdiblePopcorn extends Popcorn { 
     // if the sizzle body is always the same, you can declare it here. 
     void sizzle(); 
    } 
} 
+0

如果你只需要一個方法內的類,你也可以這樣做。 – djjeck

2

我有點沒想到這個工作,但它聲明它以上將按預期進行編譯和工作。解釋是表達式的類型new Object() {}是表達式定義的匿名類型,而不是Object。但是,該類型的變量(或方法參數)不能有,這意味着除表達式之外的鏈接之外,不能調用其他任何地方的方法。

由於這不能真正解決您的(無法解決的)問題,我承認這更多的是補充答案。

+0

不解決問題,但它是一個很好的補充:) +1 – Raffaele