Interfaces
Interfaces are abstract types that define a set of requirements (methods and/or fields). Other types can implement an interface, and the compiler checks that all the required methods and fields are provided by the implementing type.
Interfaces can also provide default implementations of methods. The implementing types will automatically inherit them. Fields defined in an interface are also automatically inherited.
interface Fooable {
int foo();
int fooSquared() {
return foo() * foo();
}
}
struct X: Fooable {
int foo() {
return 2;
}
}
void callFoo<T: Fooable>(T& f) {
println(f.foo());
}
void main() {
var x = X();
println(x.fooSquared()); // prints 4
callFoo(x); // prints 2
}Interface fields
Interfaces can also declare fields, which implementing types inherit like their own. Combined with default implementations, this lets unrelated types share both state and behavior:
interface Named {
string name = "anon";
void greet() {
println("hi ", name);
}
}
struct Person: Named {
}
struct Robot: Named {
int serial;
}
void main() {
var person = Person();
person.name = "Bo";
person.greet(); // prints "hi Bo"
var robot = Robot(42);
robot.name = "R2";
robot.greet(); // prints "hi R2"
println(robot.serial); // prints 42
}Note that the autogenerated constructor doesn't take inherited fields as parameters, so they are assigned after construction.
Enums can implement interfaces with method requirements, but not field requirements, since enums have no fields.