---
title: Interfaces
canonical_url: https://mew-lang.org/language/interfaces/
sidecar_url: https://mew-lang.org/language/interfaces.md
content_hash: sha256:40bdccf2c583a6822f02dc781fa7eb0783cbd8653f48fb5f766efa759edea3be
tokens: 1064
uid: language.interfaces
reading_time_minutes: 6
---

Language
# Interfaces

 
An interface names a set of methods. A type implements one with an `impl` block, and a method reaches the value it was called on through `self`. An `impl` block that names no interface adds members instead, which [Extending a type](https://mew-lang.org/language/extending.md) covers.

 
```mew
use std;
  
pub interface Describable {
    fn describe() -> string;
}
  
pub type Point {
    pub field x: i32;
    pub field y: i32;
}
  
impl Describable for Point {
    pub fn describe() -> string {
        return $"({self.x}, {self.y})";
    }
}
  
let point = new Point { x: 32, y: 40 };
println(point.describe());
```

 
> [!NOTE]
> Interface members are public by definition, so `pub` is not written inside an `interface` block. The implementing methods are declared like any other method.

 
A member the interface declares and the type does not supply is an error, and so is a method in an `impl` block that the interface never declared.

 
A member is a signature and nothing more, so no modifier belongs on one.

 
```mew
pub interface Maker {
    static fn make() -> i32;
}
```

 
```
Error [MEW2084]: Unexpected modifier
The interface member 'make' cannot be static
```

 
### Members the interface supplies

 
An `impl` block on the interface itself gives every implementing type a member it does not have to write. A member with a body is supplied; one without is still required.

 
```mew
impl Describable {
    pub fn shouted() -> string {
        return $"{self.describe()}!";
    }
}
  
println(new Point { x: 32, y: 40 }.shouted());
```

 
```
(32, 40)!
```

 
`self` inside one is the interface, so it can call the members the interface requires and nothing else.

 
A type that wants its own answer declares the member, and that replaces what the interface supplied.

 
```mew
impl Describable for Circle {
    pub fn describe() -> string {
        return $"a circle of {self.radius}";
    }
  
    pub fn shouted() -> string {
        return "ROUND";
    }
}
  
println(new Circle { radius: 3 }.shouted());
```

 
```
ROUND
```

 
> [!NOTE]
> An `impl` block on a generic interface covers every filling in of it, so write `Seq<T>` rather than `Seq<i32>`, the same rule an `impl ... for` block follows.

 
### Using a value through its interface

 
A type that implements an interface can be used wherever that interface is expected. This is what interfaces are for: writing one piece of code that works for every type implementing it.

 
```mew
pub type Circle {
    pub field radius: i32;
}
  
impl Describable for Circle {
    pub fn describe() -> string {
        return $"a circle of {self.radius}";
    }
}
  
pub fn announce(item: Describable) -> void {
    println(item.describe());
}
  
announce(new Point { x: 1, y: 2 });
announce(new Circle { radius: 3 });
```

 
The same holds for a variable, a field, a return type and an array.

 
```mew
let shapes = new Describable[] {
    new Point { x: 1, y: 2 },
    new Circle { radius: 3 }
};
  
let mut index = 0;
while index < shapes.count {
    announce(shapes[index]);
    index += 1;
}
```

 
Only the methods the interface declares are reachable through it. To get back to the type, check with `is` and convert with `as`.

 
```mew
let first: Describable = new Point { x: 32, y: 40 };
  
if first is Point {
    let point = first as Point;
    println($"{point.x}");
}
```

 
> [!NOTE]
> A type either implements an interface or it does not, and there is no inheritance to change that later. Assigning a type that does not implement one is an error, and a cast cannot rescue it.

 
### Implementing more than one

 
A type can implement any number of interfaces, one `impl` block each. Naming the same interface twice for the same type is an error.

 
```mew
pub interface Countable {
    fn size() -> i32;
}
  
pub type Bag {
    pub field items: i32[];
}
  
impl Countable for Bag {
    pub fn size() -> i32 {
        return self.items.count;
    }
}
  
impl Describable for Bag {
    pub fn describe() -> string {
        return $"a bag of {self.size()}";
    }
}
```

 
[Previous
                
                Types](https://mew-lang.org/language/types.md)[Next
                    
                Unions](https://mew-lang.org/language/unions.md)