Interfaces

Interfaces are like classes, but they don't include any implementation: all interface members are abstract. A class implements an interface by providing an implementation for all the interface members, and by telling the relationship using an implements declaration:

interface Closeable
  def close() as void
end

class Resource implements Closeable
  ...
  def close() as void
    -- implementation of close
  end
end

Interfaces may have method and accessor members. The syntax resembles class members, but there is no method body or end.

Note: The interfaces we discuss here are all explicit interfaces. Dynamically-typed code may also use implicit interfaces as explained in Introduction to Alore.

Multiple interface inheritance

A class may inherit only one class, but it can implement any number of interfaces. Alore supports multiple interface inheritance and single implementation inheritance. This tends to work well in practice. Multiple implementation inheritance is complex and plagued with problems such as diamond inheritance, whereas interface inheritance is mostly immune to these issues.

If a class implements multiple interfaces, separate the interface names by commas:

class A implements I1, I2, ...
  ...
end

Inheritance and interface implementation

If a class explicitly inherits another class and also implements some interfaces, give the superclass before the interfaces (here B is the inherited class):

class A is B implements I1, I2, ...
  ...
end

Standard library interfaces

The Alore standard library defines several interfaces, some of which are commonly used in programs. Here we describe the interfaces std::Iterable, std::Iterator and std::Sequence.

The definition of Iterable is as follows:

interface Iterable<T>
  def iterator() as Iterator<T>
end

The interface is generic. An Iterable object supports iteration, and the iteration produces objects of type T. Here is the definition of Iterator:

interface Iterator<T>
  def hasNext() as Boolean
  def next() as T
end

For example, Range implements Iterable<Int>, Str implements Iterable<Str> and Array<T> implements Iterable<T>.

The Sequence interface is implemented by classes which support indexing with [] using integers, such as Array and Str. Sequence is defined like this:

interface Sequence<T>
  def _get(i as Int) as T    -- Operation sequence[i]
  def length() as Int
end

For loop and Iterable

The object to iterate in a for loop must implement Iterable<T>. The type of the loop variable is inferred from the type variable T of the iterated object. In the example below the iterated object has type Range, and Range implements Iterable<Int>; therefore the type of i will be Int:

for i in 0 to 5
  Print(i + 1)
end

The above example is equivalent to the following code, with explicit types for clarity:

var iterable = 0 to 5 as Iterable<Int>
var iterator = iterable.iterator() as Iterator<Int>
while iterator.hasNext()
  var i = iterator.next() as Int
  Print(i + 1)
end

Note that the type of iterable could equally have been Range.

Interface binding

You can also set an interface to be a supertype of an existing class, directly within the interface definition. Do this with a bind declaration:

class A
  def length() as Int
    ...
  end
end

interface WithLength
  bind A       -- Set WithLength to be supertype of A

  def length() as Int
end

Now A implements WithLength, so the following is fine:

var l as WithLength
l = A()
l.length()

The above definitions are equivalent to the following code, where the class declares the implementation:

class A implements WithLength
  def length() as Int
end

interface WithLength
  def length() as Int
end

You can also bind interfaces to classes defined in other modules, including standard library classes. Sometimes it is even useful to bind interfaces to such basic types as Int or Str.

Accessors and interfaces

Interfaces may not include member variables or constants, but they can define accessors. Classes that implement an interface may use variables or constants to implement the accessors:

interface Accessors
  def n as Int
  def n = x as Int
end

class Variables implements Accessors
  var n as Int  -- Implementation of getter and setter for n
end