Interfaces
An interface is a special kind of class which only has methods and
constants, but no other kinds of fields. A class may only have one
superclass, but it may have any number of superinterfaces. Interfaces are defined much like classes,
but with the interface
keyword and abstract-by-default methods:
interface Example {
method exampleMethod(s:String):Bit
}
Classes inherit from superinterfaces just like they do superclasses:
class Foo : FooSuper, Example {
@override
method exampleMethod(s:String):Bit {
...
}
}
In addition to all the types Foo
could normally be used as (itself, FooSuper
, Object
, etc.),
Foo
is also an instance of Example
and may be used wherever an Example
is required.
Interfaces may themselves have superinterfaces:
interface Example {
method exampleMethod(s:String):Bit
}
interface BetterExample : Example {
method betterExampleMethod(s:String, o:Object)
}
Interfaces may even inherit from more than one parent interface:
interface MultipleParents : BetterExample, AnotherInterface {
...
}
Default Methods
All methods in an interface are abstract by default. You may annotate an interface method with
@default
and provide an implementation in order to create a default method:
interface Example {
method exampleMethod(s:String):Bit
@default
method defaultMethod() {
Console.printLine("this method has an implementation!")
}
}
A default method will be inherited by a class implementing this interface provided that it does not already its own implementation of the method. If two or more interfaces provide a method with the same signature, the interface listed first "wins" and its implementation will be used in preference to interfaces listed later. For example, given the code:
interface Example1 {
method exampleMethod(s:String):Bit
@default
method defaultMethod() {
Console.printLine("this method has an implementation!")
}
}
interface Example2 {
function someOtherMethod(r:Real64):Real64
@default
method defaultMethod() {
Console.printLine("this method also has an implementation!")
}
}
class Foo : Example2, Example1 {
@override
method exampleMethod(s:String):Bit {
...
}
@override
function someOtherMethod(r:Real64):Real64 {
...
}
}
The statement Foo().defaultMethod()
will result in the output
"this method also has an implementation!"
. defaultMethod()
implementations are present in both
Example1
and Example2
, but as class Foo lists Example2
first, that interface's implementation
of defaultMethod()
will be inherited. If Foo
defined its own implementation of defaultMethod
(or inherited one from a superclass), it would be used in preference to either interface's default
implementation.