Delegating interface implementation with composition
Gosu supports the language
feature called composition by using the delegate
and represents keywords
in variable definitions. A class uses composition
to delegate responsibility for implementing an interface to a different
object. This compositional model supports implementation of objects that
are proxies for other objects, or encapsulation of shared code independent
of the type inheritance hierarchy. The syntax for using the composition
feature looks like the MyWindow
class in the following code:
interface IClipboardPart {
function load()
}
class ClipboardPart implements IClipboardPart {
override function load() {
print("Gosu is loaded!")
}
}
class MyWindow implements IClipboardPart {
delegate _clipboardPart represents IClipboardPart
construct() {
_clipboardPart = new ClipboardPart(this)
this.load()
}
}
In this example, the class definition for MyWindow uses the delegate keyword to delegate implementation
of the IClipboardPart
interface. To complete the delegation, the constructor for the MyWindow class creates an object
of the ClipboardPart class.
This object is the delegate. It has the delegate’s name, _clipboardPart. When a class delegates
the implementation of an interface, it must construct the delegate it
declares. Upon doing so, the class fulfills indirectly its implementation
duty.
The class that defines a delegate object
must implement the interface that the delegate represents. In the example
code, the ClipboardPart
class defines the delegate object, _clipboardPart.
This definition implements the sole method that the IClipboardPart interface declares,
load().
When instantiating the MyWindow class, the class constructor
in the example code calls the constructor for the class that defines
the delegate object, _clipboardPart.
Upon its construction, _clipboardPart
has access to all of the methods that its defining class, ClipboardPart, implements, including
the load() method. Upon
constructing its delegate, the MyWindow
class has access to the load()
method as well.
The class constructor in the example code then calls the load() method. This method in turn calls the print() method. The print() method then writes the sentence “Gosu is loaded!” to the system console or default output stream.
You can use a delegate to represent (provide
methods for) multiple interfaces for the enclosing class. In the delegate statement, specify a
comma-separated list of interfaces. For example:
private delegate _employee represents ISalariedEmployee, IOfficerThe Gosu type system handles the type of the variable in the previous example by using a special kind of type called a compound type.
See also
