>>154090>>No one sane uses inheritance, it was and is a bad idea.
>Was für eine bescheuerte Aussage.
Er hat Recht mit dem Kern, dass Vererbung schlecht ist. Das "fast immer" spart sich Felix mal.
Dass da so echte Schotten wie "no one sane uses..." kommen, ist eher dem Ortsdialekt des dortigen Forums geschuldet (die Einzeiler müssen reinknallen).
>Clean Code
Davon ist der Pfostierer dort doch meilenweit entfernt, weil das doch auch nur wieder ein weiterer spukiger
>Spook ist. Aber dazu später mehr...
Felix nimmt im Folgenden mal die C++-Bezeichnungen, damit klarer ist, was gemeint ist. Da muss man mal schauen, was tatsächlich am Ende rauskommt.
Was Vererbung da eigentlich ist:
*Man hat ein
struct
, und will dem
struct
ein paar Variablen hinzufügen.
*Man kann der Kotbasis einige Funktionen hinzufügen, die auf dem so entstandenen
struct
arbeiten können (ein Zeiger aufs
struct
als impliziten ersten Parameter der Funktion)
*Man kann dem
struct
eine Funktionszeiger-Tabelle geben, von Funktionen, die dann ebenso auf dem so entstandenen
struct
arbeiten können
Ja leck die Wand an. Wie man den ersten Punkt erfüllt, ist klar: Man fügt dem
struct
die Sachen hinzu. Von mir aus auch mit einem weiteren
struct
. Ob man das nun "Komposition" nennt oder manuell macht oder wie auch immer bewerkstelligt, ist dafür egal. Der zweite Punkt ist auch trivial: Man schreibt halt die Funktion als freie Funktion.
Für den letzten Punkt: Es wird fast nie gebraucht, da man die Elemente nicht (z.B. in ein einziges Array) zusammenwerfen muss. Statt in ein Array alle abgeleitete Klassen
Derived1
,
Derived2
,
Derived3
reinzuschmeißen, nimmt man halt drei Arrays. Das erledigt bereits die meisten Fälle. Wenn man die Elemente doch zusammenwerfen muss, ist ein
enum
+
switch
fast immer die bessere Wahl, welche auch besseren Kot generiert (weil zur Kompilierzeit alle abgeleiteten Varianten bekannt sind, im Gegensatz zu Funktionszeigern, da kommen dann manche mit dem CRTP an).
Der einzige Fall, wo das nicht klappt, ist, wenn jemand anderes, außerhalb der eigenen Organisationseinheit (→ Conway's Law), auch in Zukunft noch weitere Klassen ableiten kann, und dem obigen Array nun plötzlich noch einige
Derived4
hinzugefügt werden. Dann muss man tatsächlich Zeiger auf Elemente speichern (weil man die Größe von
Derived4
nicht kennt), dann muss man tatsächlich auch eine Virtuelle-Funktionszeiger-Tabelle benutzten. Denn man weiß zur Kompilierzeit noch nicht, welche abgeleiteten Klassen es noch alles geben wird.
Und dieser Fall tritt ... extrem selten, praktisch nie auf? Vielleicht, wenn die Anwendung sowieso ein krasses Plugin-System (Programmier-Brummwort der frühen 2000er!) hat, bei dem eine .dll/.so dynamisch geladen wird, und nun tatsächlich ein paar von externen Leuten definierten Elemente in den eigenen Arrays rumschwirren können?
Übrigens haben die OOP-Apologeten das auch bemerkt: "Erweiterbarkeit" hieß dabei ursprünglich, dass tatsächlich _zur Laufzeit_ weitere abgeleitete Klassen hinzukommen können, von externen Dritten. Die Ummünzung von "Erweiterbarkeit" im Sinne von "Wartbarkeit" und "Clean Code" kam erst später, und hat dann schlussendlich auch die technische Grundlage verloren. Zur Laufzeit kann es weitere Klassen geben? Kann man technisch überprüfen. Der Kot ist "sauber"? Herzlich willkommen in der Laber-Anstalt.
Übrigens ist es verboten, Arrays mit Vererbung zu benutzen, ohne dass jedes Array-Element ein Zeiger ist. Das hat C mit
union
s bereits Jahrzehnte vorher gelöst (und andere Sprachen natürlich noch früher). Für den extrem seltenen Fall des externen, erst bei Laufzeit bekannten Kots direkt alle Arrays zu Zeiger-Arrays machen? Mit Kanonen auf Spatzen, danke Vererbung.
Wohlgemerkt geht das natürlich auch alles ohne Klassen, OOP, C++, sondern so ein obiges Array aus Zeigern und obige Funktionszeiger kann man auch einfach so benutzen. Dass Dinge wie die Implementierung eines Dateisystems nicht nur die Anzahl möglicher Implementierungen dynamisch hält, sondern auch noch die Menge der möglichen _Methoden_ dynamisch hält, zeigt auf, dass OOP selbst bei der Flexibilität vom uralten C überholt wird.
Was bleibt von OOP noch übrig? Ein paar
struct
s, Funktionen,
enum
s und
switch
es? In 100 Jahren mal ein Funktionszeiger?
Das ist mit
>Spook gemeint, es ist hinterm Vorhang nichts da. Aber wehe du benutzt OOP nicht, dann bist du alt und zerdengelt, und irgendjemand beschwört die spukigen OOP-Geister herauf. Spuk! Spuk! Dein Kot ist schlecht, weil ... weil da zu wenig OOP drin ist! Achso, was ist konkret schlecht? Uh äh, Spuk! Spuk! Büdde nicht bemerken, dass OOP nicht real ist, wenn man den Vorhang hochzieht.