Blocks as shortcuts for anonymous classes
In some cases, you can pass a block as a method
argument instead of an anonymous class instance. You can pass a block
if the method argument is an implementation of a functional interface.
A functional interface contains
exactly one abstract method. For example, the Gosu interface type BlockRunnable or the Java interface
type Runnable are both
functional interfaces that contain a single method called run. Passing a block is much more
concise than passing an anonymous class instance. This Gosu coding style
works with interfaces that were originally implemented in either Gosu
or Java. The parameters of the block must be the same number and type
as the parameters to the single method of the interface. The return type
of the block must be the same as the return type of that method.
For example, suppose a method signature looks like the following:
public function doAction(b : BlockRunnable)You can call this method using a block:
obj.doAction(\ -> print("Do your action here"))As a naming convention, if
an API uses a type with a name that contains the word Block, you can probably use a
block for that type.
This technique works with any interface, including interfaces defined as inner interfaces within another interface.
Example
This example demonstrates the use of a
block argument for an inner functional interface that an outer interface
defines. The MyCallbackHandler
interface contains an inner functional interface called MyCallbackHandler.CallbackBlock.
This functional interface implements a single method named run, similar to the Runnable interface. Instead of
creating an anonymous class to use the inner interface, use a block that
takes no arguments and has no return value.
This Java code defines the MyCallbackHandler interface:
public interface MyCallbackHandler {
// A functional interface within this interface
public interface CallbackBlock {
public void run() throws Throwable;
}
// ...
public void execute(CallbackBlock block) throws Throwable;
}
This Gosu code creates the anonymous class explicitly:
public function messageReceived(final messageId : int) : void {
var _callbackHandler : MyCallbackHandler
// Create an anonymous class that implements the inner interface
var myBlock : _callbackHandler.CallbackBlock = new MyCallbackHandler.CallbackBlock() {
// Implement the run() method in the interface
public function run() : void { /* Your Gosu statements here */ }
}
// Pass the anonymous inner class with the one method
_callbackHandler.execute(myBlock)
}
You can code the method more concisely by using a block:
public function messageReceived(messageId : int) {
_callbackHandler.execute(\ -> { /* Your Gosu statements here */ })
}
