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 Dog;
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.
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();
}
}