Parameterizing a class
To specify a class that operates with a generic type, define the class with the angle bracket notation
CLASSNAME<GENERIC_TYPE_WILDCARD>. By convention,
for GENERIC_TYPE_WILDCARD, use a one-letter name, preferably T. For
example, you could define a class MyClass as MyClass<T>.
In the following example, the class Genericstest has one method that returns the first item in a list. Gosu strongly types the return value to match the type of the items in the collection:
class GenericsTest<T> {
// Print out (for debugging) and then return the first item in the list, strongly typed
public function printAndReturnFirst(aList : ArrayList<T>) : T {
print(aList[0])
return aList[0]
}
}
Other code can use this class and pass an array list of any type to the method:
var myStrings = new ArrayList<String>(){"a", "abcd", "ab", "abc"}
var t = new GenericsTest<String>()
var first = t.printAndReturnFirst(myStrings)
The variable first is strongly typed as String at compile time because the code
uses a method that was defined with generics.
Because the code is strongly typed at compile time, the reliability of the code improves at run time.
Instantiating a generic class
- Using the type token for the type parameter requires information about the type at run
time. If you instantiate a generic class in this way in a parameterized method, you must
use the
reifiedkeyword in the method declaration. This instantiation creates a strongly typed object that uses the explicit type that is reified by the method. For example, in the following lines of code, the type of the variable x isGenericsTest<T>where T is the type of the method parametert:public reified function makeANewGenericOfSpecifiedType<T>(t : T) { var x = new GenericsTest<T>() } - Specifying the type of the type parameter creates a strongly typed object that uses
the explicit type. For example, in the following line of code, the type of the variable
x is
GenericsTest<Integer>:public function makeANewGenericOfSpecificType() { var x = new GenericsTest<Integer>() }You can include this instantiation of
GenericsTestin a parameterized method without using thereifiedkeyword because you have provided Gosu with the necessary information for the type parameter. - Omitting the type parameter creates a strongly typed object that uses the least
restrictive type of the bound. For example, in the following line of code, the type of
the variable x is
GenericsTest<Object>:public function makeANewGenericOfNonspecificType() { var x = new GenericsTest() }You can include this instantiation of
GenericsTestin a parameterized method without using thereifiedkeyword because Gosu substitutes the least restrictive type that is available for the type parameter.
Enhancements of generic classes
If you create an enhancement of a generic class, you must use the correct syntax:
- For a generic enhancement, you parameterize both the enhancement name and the class name. For example, the
declaration of a generic enhancement to the GenericsTest class looks like the following
line.
enhancement GenericsTest_Enh<T> : GenericsTest<T> - For an enhancement that applies to a specific type on the generic class, you specify the type only on the
class name. For example, the declaration of an enhancement to the
Stringtype of the GenericsTest class looks like the following line.enhancement GenericsTest_StringEnh : GenericsTest<String>
See also
