Defining and using an interface

In some ways, interfaces are similar to Gosu classes. There is no separate top-level folder in Studio for interfaces.

A Gosu interface can have the following content and properties:
  • Empty methods, for which the implementing class must provide code
  • Default methods, which include code and which the implementing class can use as is or can override
  • Static variables and methods
  • Properties
  • Extending from a Java interface
  • Extend from a Java interface that supports generics
  • Including Gosu generics
  • Abstracting an interface across a type defined in Java or a subtype of such a type

You use the implements keyword in a class declaration to specify the interfaces that the class implements. If a class implements more than one interface, separate the interface names by commas:

class MyRestaurant implements Restaurant, InitializablePlugin

The Gosu editor reveals compilation errors if your class does not properly implement the plugin interface. You must fix these issues.

When subclassing a parent class or implementing an interface, you can override the methods defined in the parent class or interface.

To call the method that a parent class defines, use the super keyword using the following syntax:
super.method
For example, if a parent class defines a no-argument method makeJourney, the subclass can call the parent implementation like the following line:
super.makeJourney()
To call a default method that an interface defines, use the super keyword using the following syntax:
super[interface].method
For example, if an interface Travel defines a no-argument method comeHome that contains default code, the implementing class can call the default implementation like the following line:
super[Travel].comeHome()
Note: When overriding the equals method for objects, which is a common technique for overriding the == operator, you must also override the hashCode method. You must use logic ensuring that the return value for a.equals(b) always matches the return value for a.hashCode() == b.hashCode().

In the following example, IMyInterface defines a property called Name, and a default method called speak. The class MyClass implements the interface and calls the default method:

interface IMyInterface {
  property get Name() : String
  property set Name(n:String) : void
  function speak() : String {
    return "Hello World"
  }
}

class MyClass implements IMyInterface {
  var _name : String

  override property get Name() : String {
    return "name: " + _name
  }

  override property set Name(n:String) {
    _name = n
  }

  override function speak() : String {
    return "Hello, " + _name
  }

  function shout() : String {
    return (super[IWithDefaultMethod].speak() + 
            "\n" + gw.api.util.StringUtil.toUpperCase(super[IWithDefaultMethod].speak())
  }
}

This code creates an instance of MyClass and tests the overridden Name property and the default method:

var myObject = new MyClass()
myObject.Name = "Andy Applegate"
print(myObject.Name)
print(d.speak())
print(d.shout())
In this example, myObject is an object of type MyClass, which has overridden the IMyInterface properties, and calling myObject.Name("Andy Applegate") sets the private variable _type to "Andy Applegate". As the print function is called, the value returned by myObject.Name is "name: Andy Applegate". The code also prints the default output from the overridden speak method and the output from the shout method that calls the default method in the interface. The output looks like the following lines:
name: Andy Applegate
Hello, Andy Applegate
Hello World
HELLO WORLD

See also