Declarations
Interfaces
Declare the members a class must provide, including fields, and let any class satisfy them by declaring those members.
since 0.1.0-alpha.1linuxwindowswasm
Description
An interface lists the members that an implementing class must have:
interface IName {
int x;
string f();
}
An interface can require fields as well as methods. It does not allocate anything: it only states what must be present. The class that lists the interface after its colon supplies the members and is the only place a field is allocated. As a result two interfaces can require the same field without conflict, and the class holds a single field for both.
A variable whose type is an interface can hold an object of any class that implements it, and calls through it dispatch on the object's class.
Implementing two interfaces that share a field
interface INamed { string name; string describe(); }
interface IAged { int age; string name; }
class Person : INamed, IAged {
string name = "Ada";
int age = 36;
string describe() => name + " (" + age.toString() + ")";
}
INamed n = Person();
console.writeln(n.describe());
IAged g = Person();
console.writeln(g.age);
console.writeln(g.name);
Ada (36)
36
Ada
Rules
- A class satisfies an interface when it provides every required member. A missing member, or a
member with the wrong type, is a compile error naming the unsatisfied requirement. A member
that satisfies a requirement may be marked
override(lang.override). - A method satisfies a required method when the names and the parameter types match exactly and the method's return type is assignable to the required return type.
- Interface method returns are covariant: a method may declare a return type that is a class (or
interface) derived from the required return type. A class
DogFinderwhosefindreturnsDogsatisfies an interface requiringAnimal find(). - A class or interface return type
Talso satisfies a requiredT?. Other optional and union returns, function types, primitives andvoidmust match the requirement exactly. - Covariance applies only to satisfying an interface. Narrowing the return type of a method in a derived class does not override the base class's method; it declares a separate method, and calls through the base type still reach the base class's method.
- Requirements allocate no slot, so dispatch through an interface variable reaches the implementing class's single method.
Examples
A class can return a more specific type than the interface requires, including where the requirement is optional:
Covariant return types
class Animal { string kind() => "animal"; }
class Dog : Animal { string kind() => "dog"; }
interface IFinder { Animal find(); Animal? maybeFind(); }
class DogFinder : IFinder {
Dog find() => Dog();
Dog maybeFind() => Dog();
}
IFinder f = DogFinder();
console.writeln(f.find().kind());
Animal? a = f.maybeFind();
if (a != None) {
console.writeln(a.kind());
}
dog
dog
Narrowing a return type in a subclass does not override:
Covariance is for interface satisfaction only
class Animal { string kind() => "animal"; }
class Dog : Animal { string kind() => "dog"; }
class Kennel {
Animal pick() => Animal();
}
class DogKennel : Kennel {
Dog pick() => Dog();
}
Kennel k = DogKennel();
console.writeln(k.pick().kind());
animal
An unsatisfied requirement is reported when the class is declared:
A missing member
interface INamed { string name; string describe(); }
class Person : INamed {
string name = "Ada";
}
// error: 'Person' does not satisfy interface: missing 'describe : () -> string'
A required optional return is satisfied by the plain type:
T satisfies T?
class Animal { string kind() => "animal"; }
interface IFinder { Animal? find(); }
class AF : IFinder {
Animal find() => Animal();
}
See also
- Classes — Declare reference types with fields, methods, constructors and accessors, with generics and inheritance from one or more base classes.
- Multiple inheritance — Combine several base classes, how same-named fields and methods collapse or stay separate, and how to reach one base's member by qualification.