2011-12-12 79 views
3

以下面的例子。有一個我想使用的對象,稱它爲DoodadDoodad元素對瀏覽器事件的處理效果很差。典型的Doodad實例化將是Doodad someDoodad = new Doodad();。很明顯,這不適合我的需求,因爲糟糕的事件處理。是不是適合我重寫onBrowserEvent()方法,像這樣:匿名內部類:他們什麼時候適合?

Doodad someDoodad = new Doodad() { 
@Override 
    public void onBrowserEvent(Event event) { 
     switch (DOM.eventGetType(event)) { 
      case Event.ONDBLCLICK: 
      case Event.ONFOCUS: 
      case Event.ONCLICK: 
       if (!isEnabled()) { 
        return; 
       } 
       break; 
     } 
     super.onBrowserEvent(event); 
    } 
}; 

顯然,這是一個簡單的例子,但是當我可能不會希望使用匿名內部類?它是否被明確禁止或不可能?

我看到很多第一個問題的答案,但目前爲止的答案都沒有回答第二個問題:是否明確地禁止或不可能使用匿名內部類?

+0

像上面的例子,大部分是我在事件處理案例中看到的。 –

回答

6

通常,匿名內部類的最佳用法是當您只想創建此類的特定實現的一個實例時。而且實現非常簡單。理想情況下,它應該包含1-2行代碼。你的方法onBrowserEvent()比2行更長。

+1

爲了公平起見,OP使用switch語句而不是if語句將2行變爲6。 – corsiKa

+0

@glowcoder它是6行來說明問題:什麼時候適合使用匿名內部類。我可以用兩行完成同樣的事情,但希望看到與代碼長度(實際用法)以及功能用法有關的答案。 –

+0

我更喜歡將方法添加到枚舉中。在這種情況下,我會定義方法'proceedBrowserEvent'併爲每個枚舉成員實現它。在這種情況下,監聽器應該真的調用一個方法,所以它將是一行。 – AlexR

0

我的看法:

匿名內部類:回調從一個功能(這樣你就不會寫代碼的兩倍)

命名的內部類:回調從幾個函數(或者,你只需要一個類對於父類的內部邏輯)

1

通常情況下,事件偵聽器是一段不是非常通用的代碼,但與特定的小部件,按鈕,文本字段等無關。在這種情況下,代碼不需要適當地公開以供世界重用。定義它在何處使用就更容易了,這就是匿名內部類的用途。它們允許在另一種方法中快速嵌入代碼段,而不必擔心類名稱,包,可見性或可重用性。

當然,你可以用匿名內部類來做什麼,總是可以用適當的獨立類來完成。但是當你的事件處理類足夠通用時(可以處理大量事件),可重用的,有狀態的,或者當從代碼中提取事件管理代碼有一些好處時,這樣做更有意義定義事件生成元素。

我不確定我明白你的問題,我希望這條信息能幫助你找到答案。不要猶豫提出進一步的問題。

3

匿名內部類是創建閉包的Java語法。這裏有一個近似的例子:

interface Adder { 
    int add(int arg); 
} 

... 

Adder createAdder(int n) { 
    final int nf = n; 
    return new Adder() { 
     int add(int arg) { return arg + nf; } 
    } 
} 

方法createAdder創建本質上是一個函數,使用閉包捕獲傳遞的值n。功能編程正在試圖使其成爲主流,關閉是非常重要的。這就是爲什麼大家都尖叫我們需要Java中的「真正」關閉(即大多數語法比我的例子更好)。 (當然,我並沒有回答所問的問題,我想我的意思是匿名課程對我上面描述的很有幫助。幾乎所有我會創建一個命名的內部類,因爲如果任何名稱是自我記錄,並在我看來更容易閱讀)

+2

真正的關閉不會要求捕獲變量標記爲最終... – gizmo

+0

是的,你需要手動捕獲它們的事實很糟糕,但它只是語法上的,而不是功能上的缺陷。 –

1

我會建議匿名類,當它實現一種方法和/或是半滿屏幕。

如果匿名非代碼段的代碼具有命名類恕我直言。

+0

「糟糕的事件處理」是什麼意思? –

+0

在OP中,我提到「Doodads的事件處理能力很差。」假設它在「禁用」時不正確地處理點擊。 –

+0

該類是否被命名或匿名對它的行爲沒有影響(除了默認的'toString'),如果它具有'糟糕的事件處理',如果它被命名,它仍然會有這個。 –

0

當只包含非常少量的代碼時,我只使用匿名內部類。原因在於IMO混淆了代碼並使其不易讀。

如果需要更多的代碼,我希望創建一個新的類,擴展基類(在這種情況下,「裝飾物()」

+0

定義「非常少量的代碼」... –

+0

你的例子對我來說可以,但除此之外,我傾向於創建一個單獨的類。 –

0

在您的例子,你想創建一個單獨的類。這是因爲你忽略了這個方法的原因,也就是說,對瀏覽器事件的處理很差。

具體來說,你可能想要在幾個不同的地方創建這些改進的Doodads。在未來更新和改進?你會想要刪除所有這些改進的Doodads並使用正確的實現。試圖找到你所有的匿名Doodads可能是煩人的或棘手的。而如果你有一個單獨命名的類然後重構此類將很容易。

此外,如果您爲它創建單獨的類,則您改進Doodad的原因可以是自記錄。而如果你只有一個匿名類,那麼你將不得不寫評論或者讓未來的維護者猜測你爲什麼完成了你所做的事情。

例如。類似於封閉

public class ImprovedBrowserEventHandlingDoodad extends Doodad { 
    ... 
} 

任何通常是使用匿名類

如一個很好的候選人。

new Thread(new Runnable() { 
    @Override 
    public void run() { 
     doSomething(); 
    } 
}).start(); 

你只想做一些在這其中某些特定情況下,沒有必要複製和粘貼代碼別的地方或將其重構爲一個方法。

GUI的事件處理程序在使用匿名類時很常見,因爲它們的使用僅限於GUI的設計方式,並且不需要在使用它的特定組件外創建單獨的事件處理程序實例。例如,當您將鼠標懸停在滾動條上時,其外觀通常會更改。程序中沒有其他任何東西會導致這種變化,通常事件處理程序會有兩行告訴滾動條改變其外觀,例如。 scrollbar.setMouseOverEffect(true);