Klassen

D unterstützt die Verwendung von Klassen und Interfaces ähnlich wie Java or C++.

Jeder class-Typ erbt implizit von Object.

class Foo { } // erbt von Object
class Bar: Foo { } // Bar ist auch ein Foo

In D werden Klassen generell mit new auf dem Heap instanziiert:

auto bar = new Bar;

Klassenobjekte sind immer Referenztypen. Anders als structs, die beim Aufruf kopiert werden (engl: call by value), werden Objekte nur als Referenz weitergereicht (engl.: call by reference).

Bar bar = foo; // bar zeigt auf foo

Der Garbage Collector stellt sicher, dass der genutzte Speicher wieder freigegeben wird, sobald keine Referenzen mehr auf das Objekt existieren.

Vererbung

Wenn eine Memberfunktion einer Basisklasse überschrieben wird, muss das Schlüsselwort override benutzt werden, um dies anzuzeigen. So wird ungewolltes Überschreiben von Funktionen vermieden.

class Bar: Foo {
    override functionFromFoo() {}
}

In D können Klassen nur von Klassen erben.

Final und abstract Memberfunktionen

  • Eine Funktion kann als final markiert werden, um das Überschreiben zu verbieten
  • Eine Funktion kann als abstract markiert werden, um das Überschreiben zu erzwingen
  • Eine ganze Klasse kann als abstract deklariert werden, um sicherzustellen, dass sie nicht instanziiert wird
  • super(..) dient zum expliziten Aufruf des Basiskonstruktors

Prüfen der Identität

Der Inhalt von Klassenobjekten wird mithilfe der Operatoren == and != verglichen. Daher ist der Vergleich gegen null nicht zulässig, da null keinen Inhalt besitzt. Das is vergleicht die Identität von Objekten. Um auf Nicht-Identität zu prüfen, sollte e1 !is e2 verwendet werden.

MyClass c;
if (c == null)  // Fehler
    ...
if (c is null)  // Ok
    ...

Bei struct-Objekten werden alle Bits verglichen, für andere Operanden-Typen ist Identität gleichwertig mit Gleichheit.

Weiterführende Quellen

rdmd playground.d