Classes and Object-Oriented Programming
12.1 Classes (Reference Types)
Single inheritance of classes, plus multiple interfaces. All classes inherit from Object.
Methods are virtual by default. final prevents overriding. Private/final methods are non-virtual.
Classes are reference types, so null is possible. Compare identity with is.
class Animal
{
protected string name; // visible to subclasses and the module
private int id; // module-private
this(string name) { this.name = name; }
void speak() { writeln(name, " makes a sound"); } // virtual by default
final string getName() { return name; } // can't be overridden
override string toString() const { return "Animal(" ~ name ~ ")"; }
}
class Dog : Animal
{
this(string name) { super(name); }
override void speak() { writeln(name, " says Woof"); } // `override` is required
}
void main()
{
Animal a = new Dog("Rex"); // heap-allocated (GC) reference
a.speak(); // dynamic dispatch → Dog.speak
if (auto d = cast(Dog) a) writeln("It's a dog"); // downcast (null if it fails)
writeln(typeid(a)); // runtime type info
}12.2 Object Methods
String representation (used by writeln) Equality for == Ordering for < etc.
Hashing for associative array keys
12.3 Constructors, Destructors and Static Constructors
Class destructors are finalizers (non-deterministic under the GC). Use structs with destructors, scope objects, or destroy(obj) for deterministic cleanup.
class Service
{
static Service instance;
static this() { instance = new Service(); } // module/thread-local static constructor
shared static this() { /* runs once per program */ }
this() { writeln("ctor"); }
this(int x) { this(); } // constructor delegation
~this() { /* finalizer: runs on GC collection, order not guaranteed */ }
}12.4 Scope Classes and Stack Allocation
scope auto obj = new Service(); // allocated on the stack (DIP1000), destroyed at scope exit
import std.typecons : scoped;
auto s = scoped!Service(); // explicit stack allocation12.5 Nested and Inner Classes
class Outer
{
int x = 5;
class Inner { int get() { return x; } } // has an implicit `outer` reference
static class StaticNested {} // no outer reference
}
auto o = new Outer;
auto i = o.new Inner;12.6 Templates on Classes, super, this and Covariance
class Base { Base clone() { return new Base; } }
class Derived : Base { override Derived clone() { return new Derived; } } // covariant return