2010-10-08 9 views
10

Ich benutze Interfaces/abstrakte Basisklassen für die meisten meiner Typen und erben nicht oft von konkreten Klassen, aber ich bin kürzlich in eine Situation geraten, in der entweder Vererbung oder Komposition gewünscht wird. Ich war mir des Sprichwortes "Programm zu einer Schnittstelle, keine Implementierung" bewusst, entschied mich aber kürzlich, tiefer zu graben.Ist die Vererbung von konkreten Klassen böse?

Ich habe Argumente gesehen againstinheritance, und ich habe gesehen Zähler arguments aber ich bin neugierig, was andere Maintainer von großen Codebasen tun tatsächlich im wirklichen Leben. Ist die Angst übertrieben? Erben Sie von konkreten Klassen oder sind die Vererbungsskeptiker korrekt? Ich bin besonders daran interessiert, von den Leuten zu hören, die in C++ arbeiten.

+1

Weitere Details würden helfen. Das ist grenzwertig keine echte Frage. – Potatoswatter

+0

Nein, es ist nicht böse. Es ist nur, dass es oft nicht das Richtige ist. Ohne weitere Details ist es schwierig, Ihren Fall zu beurteilen. – jcoder

+0

Vererbung ist ein Werkzeug, es ist nicht von Natur aus gut oder böse - es hängt davon ab, wie es verwendet wird. –

Antwort

11

keine C++ Typ (professionelle Erfahrung mit großen Enterprise-Systemen in C#, Java und Ruby), aber hier ist mein 2 Cent sowieso

Dies ist keine Schwarz-Weiß-Sache.

Das Problem mit der Vererbung ist, dass es eine enge Kopplung einführt. Schlimmer noch, diese Kopplung ist normalerweise im gekapselten Zustand. Änderungen in Super-Klassen können Auswirkungen auf die Vererbungshierarchien haben und zu subtilen und schwer vorhersehbaren Fehlern führen.

Die Schnittstellentrennung vermeidet diese Probleme völlig, da sie die Kapselung nicht auf die gleiche Weise unterbricht.

Das Gute an der Vererbung ist, dass Sie manchmal ein Objektmodell haben, das wirklich das Gleiche ist, nur mit einer sehr kleinen Änderung oder Ergänzung. Solange diese Änderung sehr klar ist, nicht weit reichend ist und keine zusätzliche Beschränkung darstellt (siehe circle-ellipse Problem), wird die Wiederverwendung von Code die enge Kopplung übertrumpfen.

Ich bleibe bei der Zusammensetzung über die Vererbung als Faustregel, kein Gesetz.

+0

Oh hey. Nur ein Heads-Up, dein Avatar ist identisch mit Mike Stones. Ich fragte ihn tatsächlich danach und er sagte zu mir, dass er den Avatar selbst gemacht hat, indem er Bild für Bild durch die bestimmte Episode gegangen ist und den Hintergrund manuell bearbeitet hat. Ich glaube nicht, dass er es zu schätzen wusste, dass Leute seinen Avatar zerfetzten. :-( –

+0

@Chris: Oh Mist.Ich habe es tatsächlich von einem Buddys-MSN-Avatar gerissen (der kein Mike-Stein ist und ironischerweise kein Problem damit hatte, dass ich es benutze), dachte er, er hat es gerade von einer Google-Suche bekommen. Ich werde es so schnell wie möglich ändern. –

+1

@Chris: bekam einen Fry, der seinen Scooter-Puff junior von irgendeiner zufälligen Avatar-Seite fliegt, sollte sich ändern, wenn SO ihre Caches ablaufen lässt. Was ist die Wahrscheinlichkeit, dass etwas, das Sie über MSN bekommen, sich als das liebevoll gestaltete Produkt eines echten aktiven Benutzers eines Forums herausstellt, auf dem Sie gerade aktiv sind? –

4

Sie können privat von konkreten Klassen ableiten. Private Vererbung erfordert keine Austauschbarkeit von Liskov; es ist im Wesentlichen nur eine bequeme Möglichkeit, die Funktionalität einer Klasse zu "mischen".

Öffentliche Vererbung, auf der anderen Seite erfordert Liskov Substituierbarkeit. Normalerweise ist das öffentliche Erben von konkreten Klassen eine schlechte Sache, es sei denn, eine solche Klasse ist als Basisklasse konzipiert (viele nicht).

+0

Viele, die nicht so entworfen sind, können auch ein wenig umgestaltet/verfeinert werden, um es zu unterstützen. – Potatoswatter

2

Gutes Design schreibt vor, dass Betonklassen ein einzelnes, relativ kleines Ding gut und effizient machen sollten. Insbesondere in C++ betonen Betonklassen ihre Ähnlichkeit mit Betontypen wie int und char, oft durch Überlastung des Operators und durch nur nicht-virtuelle Funktionen. Da konkrete Klassen kein polymorphes Verhalten anzeigen sollen, sollten sie nicht vererbt werden. Siehe auch Abschnitt 25.2 von The C++ Programming Language für weitere Informationen über die korrekte Verwendung von Betontypen in dieser Sprache.

Verwandte Themen