Interfaces

D allows defining interfaces which are technically like class types, but whose member functions must be implemented by any class inheriting from the interface.

interface Animal {
    void makeNoise();
}

The makeNoise member function has to be implemented by Dog because it inherits from the Animal interface. Essentially makeNoise behaves like an abstract member function in a base class.

class Dog: Animal {
    override makeNoise() {
        ...
    }
}

auto dog = new Animal;
Animal animal = dog; // implicit cast to interface
dog.makeNoise();

The number of interfaces a class can implement isn't limited, but it can inherit from only one base class.

NVI (non virtual interface) pattern

The NVI pattern prevents the violation of a common execution pattern by allowing non virtual methods for a common interface. D easily enables the NVI pattern by allowing the definition of final functions in an interface that aren't allowed to be overridden. This enforces specific behaviours customized by overriding the other interface functions.

interface Animal {
    void makeNoise();
    final doubleNoise() // NVI pattern
    {
        makeNoise();
        makeNoise();
    }
}

In-depth

rdmd playground.d