Objektorientierte Programmierung
In objektorientierter Programmierung werden Daten und Methoden gemeinsam in Typen
gebündelt. Die Methoden können auf den Daten operieren. Beispielsweise beinhalten in
Rust struct
s und enum
s sowohl Daten als auch Methoden, wobei die Methoden
per self
auf die Daten zugreifen können. Folgende Aspekte werden häufig mit
objektorientierter Programmierung in Verbindung gesetzt.
Kapselung
Wenn nun nur die Methoden auf interne Daten zugreifen, wird der unnötige Pfusch
des gemeinen Benutzers mit Implementierungsdetails verhindert. Wenn die Typen jedoch
zu groß werden, verbirgt sich hinter self
sehr oft eine unnötig große Vielfalt an
Feldern, so dass die meisten Methoden nur Zugriff auf einen Bruchteil der zur Verfügung
stehenden Daten benötigen.
Kapselung im Sinne objektorientierter Programmierung ist dementsprechend nur effektiv,
solange die Typen übersichtlich bleiben.
In des Autors Programmiererleben haben Tendenzen ewigen Typwachstums bedauerlicherweise
eine signifikante Rolle gespielt.
Vererbung
In vielen objektorientierten Sprachen können Typen direkt voneinander erben. Dabei
ist es dem Erbenden über self
-artige Konstrukte möglich, nicht nur auf Methoden sondern auch auf Felder sämtlicher Vorfahren
zuzugreifen. Zuträglich ist das vor allem der Mannigfaltigkeit des Datenspektrums, dass
sich hinter self
verbirgt. Übersichtlicher werden Programme dadurch eher nicht. Glücklicherweise
ist das in Rust nicht möglich. In Rust können nur Traits von Traits erben wie im Kapitel über Traits
dargestellt.
Eine Motivation für die Verwendung von Vererbung ist die Vermeidung von Code-Duplikation. In Rust erinnern wir uns neben der Möglichkeit einfach freie Funktionen zu verwenden, an Standardimplementierungen von Trait-Methoden. Die Verwendung von Vererbung in objektorientierten Sprachen ausschließlich zur Verringerung von Code-Duplikation ist mindestens kontrovers. Aggregation von Typen in Feldern wird oft der Vererbung vorgezogen.
Ein weiterer deutlich besserer Grund zur Verwendung von Vererbung ist dynamische Polymorphie. Wir möchten also Funktionalität für verschiedene Gestalten eines Konzepts wiederverwenden. In diesem Fall möchten wir also Funktionalität für alle Erben zugänglich machen.