Moin!
Das Problem an Vererbung ist, dass es zwei Klassen direkt und hart miteinander koppelt ohne eine Möglichkeit, diese in irgendeiner Form voneinander zu trennen.
sehe ich genauso und habe ins geheim gehoft das das nur anfängerverständnis ist.
Es gibt Einsatzgebiete, wo dies sinnvoll ist, aber diese sind seltener als man zuerst denkt.
zb?
Wenn es tatsächlich um Code geht, der untrennbar zu einem Thema gehört, bzw. zueinander gehörend betrachtet wird. Beispielsweise wird man tausendundeinen unterschiedlichen Validator für Formularwerte erfinden können, aber die grundsätzliche Infrastruktur eines Pakets, dass sich mit Validierung beschäftigt, könnte jeder einzelne Validator von einer abstrakten Klasse erben, sofern es dabei um mehr als nur den gemeinsamen Konstruktor geht.
Dinge, die ich auch über Vererbung lösen würde: Eine Klasse hat den Code und protected properties mit bestimmten Settings, und eine davon erbende Klasse ändert nur an diesen Settings.
Aber tatsächlich sollte man viel weniger auf Vererbung setzen, und mehr auf Zusammensetzung/Komposition. Das gilt vermutlich auch für das Validator-Beispiel: Was bringt es einem, einen Validator zu schreiben, der zwingend von einer vorliegenden abstrakten Klasse deren Infrastruktur-Implementierung erben muss, wenn man die gar nicht braucht? Als Autor des Validatorpakets ist es eventuell sinnvoll, nicht alles doppelt zu schreiben, aber andererseits ist der Nutzen für den Rest der Welt größer, wenn man auch nur einen einzelnen Validator benutzen könnte, ohne Zeugs drumrum. Bei Vererbung ist "ohne Zeugs drumrum" nicht machbar.
Grüße Sven