摘要:
Java接口提供了一個很好的方法來實現回調函數。假如你習慣於在事件驅動的編程模型中,經過傳遞函數指針來調用方法達到目的的話,那麼你就會喜歡這個技巧。
做者:John D. Mitchell
在MS-Windows或者X-Window系統的事件驅動模型中,當某些事件發生的時候,開發人員已經熟悉經過傳遞函數指針來調用處理方法。而在Java的面向對象的模型中,不能支持這種方法,於是看起來彷佛排除了使用這種比較溫馨的機制,但事實並不是如此。
Java的接口提供了一種很好的機制來讓咱們達到和回調相同的效果。這個訣竅就在於定一個簡單的接口,在接口之中定義一個咱們但願調用的方法。
舉個例子來講,假設當一個事件發生的時候,咱們想它被通知,那麼咱們定義一個接口:
public interface InterestingEvent
{
// This is just a regular method so it can return something or
// take arguments if you like.
public void interestingEvent ();
}
這就給咱們一個控制實現了該接口的全部類的對象的控制點。所以,咱們不須要關心任何和本身相關的其它外界的類型信息。這種方法比C函數更好,由於在C++風格的代碼中,須要指定一個數據域來保存對象指針,而Java中這種實現並不須要。
發出事件的類須要對象實現InterestingEvent接口,而後調用接口中的interestingEvent ()方法。
public class EventNotifier
{
private InterestingEvent ie;
private boolean somethingHappened;
public EventNotifier (InterestingEvent event)
{
// Save the event object for later use.
ie = event;
// Nothing to report yet.
somethingHappened = false;
}
//...
public void doWork ()
{
// Check the predicate, which is set elsewhere.
if (somethingHappened)
{
// Signal the even by invoking the interface's method.
ie.interestingEvent ();
}
//...
}
// ...
}
在這個例子中,咱們使用了somethingHappened這個標誌來跟蹤是否事件應該被激發。在許多事例中,被調用的方法可以激發interestingEvent()方法纔是正確的。
但願收到事件通知的代碼必須實現InterestingEvent接口,而且正確的傳遞自身的引用到事件通知器。
public class CallMe implements InterestingEvent
{
private EventNotifier en;
public CallMe ()
{
// Create the event notifier and pass ourself to it.
en = new EventNotifier (this);
}
// Define the actual handler for the event.
public void interestingEvent ()
{
// Wow! Something really interesting must have occurred!
// Do something...
}
//...
}
但願這點小技巧能給你帶來方便。
關於做者: John D. Mitchell在過去的九年內一直作顧問,曾經在Geoworks使用OO彙編語言開發了PDA軟件,愛好於寫編譯器,Tcl/Tk和Java系統。和人合著了《Making Sense of Java》,目前從事Java編譯器的工做。