Interface Inheritance

Get familiar with the concepts of interfaces in general and the interface inheritance in detail.

Interfaces

The interface keyword is for defining interfaces in class hierarchies. interface is very similar to class with the following restrictions:

  • The member functions that it declares (but not implements) are abstract even without the abstract keyword.

  • The member functions that it implements must be static or final. (static and final member functions are explained later in this chapter.)

  • Its member variables must be static.

  • Interfaces can inherit only interfaces.

Despite these restrictions, there is no limit on the number of interfaces that a class can inherit from. This is unlike classes where a class can inherit from up to one class only.

Definition

Interfaces are defined by the interface keyword, the same way as classes:

interface SoundEmitter {
    //....
}

An interface is for declaring member functions that are implicitly abstract:

interface SoundEmitter {
    string emitSound();    // Declared (not implemented)
}

Classes that inherit from that interface would have to provide the implementations of the abstract functions of the interface. Interface function declarations can have in and out contract blocks:

interface I {
    int func(int i)
    in {
        /* Strictest requirements that the callers of this
         * function must meet. (Derived interfaces and classes 
         * can loosen these requirements.) */
    } out {    // (optionally with (result) parameter)
        /* Exit guarantees that the implementations of this
         * function must give. (Derived interfaces and classes
         * can give additional guarantees.) */
    } 
}

Inheriting from an interface

The interface inheritance syntax is the same as class inheritance:

class Violin : SoundEmitter {
    string emitSound() {
        return "♩♪♪"; 
    }
}

class Bell : SoundEmitter {
    string emitSound() {
    return "ding";
    }
}

Interfaces support polymorphism: Functions that take interface parameters can use those parameters without needing to know the actual types of objects. For example, the following function that takes a parameter of SoundEmitter calls emitSound() on that parameter without needing to know the actual type of the object:

void useSoundEmittingObject(SoundEmitter object) { 
    // ... some operations ... 
    writeln(object.emitSound());
    // ... more operations ...
}

Just like with classes, that function can be called with any type of object that inherits from the SoundEmitter interface:

Get hands-on with 1200+ tech skills courses.