Interfaces
Also known as: interface trait protocol abstract class polymorphism dynamic dispatch virtual method duck typing implements inheritance
● Intermediate5 minBefore this: Methods, GenericsSpec 2.8
An interface names methods a type promises to have. A type keeps the promise only when it says so.
interface Describe {
fn describe(self) -> String
}
type User: Describe {
name: String
fn describe(self) -> String { "User {self.name}" }
}
type Rect {
width: Int
height: Int
}
extend Rect: Describe {
fn describe(self) -> String { "Rect {self.width}x{self.height}" }
}
fn show<T: Describe>(item: T) -> String {
item.describe()
}
fn main() {
print(show(User(name: "Asha")))
print(show(Rect(width: 2, height: 3)))
}The program ran and printed:
kavach run interfaces.kav
User AshaRect 2x3
type User: Describepromises adescribemethod; leaving it out is an error.extend Rect: Describeadds the promise to a type declared elsewhere.<T: Describe>accepts any type that keeps it.
A type that happens to have the method but never said so doesn't count, and the message says what to write:
interface Describe {
fn describe(self) -> String
}
fn show<T: Describe>(item: T) -> String {
item.describe()
}
fn main() {
print(show("text"))
}The compiler refused the program:
kavach run interfaces-say-so.kav
error: `String` does not implement `Describe`: write `extend String: Describe`A method that keeps the promise has the interface's types: its parameters, its value and its error, with Self read as the type and the interface's type arguments put in. Getter<String> promises a get that gives a String:
interface Getter<T> {
fn get(self) -> T
}
type Name: Getter<String> {
text: String
fn get(self) -> Int {
self.text.len()
}
}
fn main() {
const g: Getter<String> = Name(text: "Ada")
print(g.get())
}The compiler refused the program:
kavach run interfaces-same-types.kav
error: `Name.get` gives `Int`, and `Getter<String>.get` gives `String`: they must matchOther languages call this a trait or a protocol.