2009-06-09 11 views
5

Wenn ich eine abstrakte Klasse und abgeleitete Klassen dieser Klasse habe, korrigiere ich, dass die abgeleiteten Klassen nach guter und praktischer Designpraxis keine zusätzlichen öffentlichen Methoden bereitstellen (sie sollten nur abstrakte Klassen implementieren und optional übergeordnete Methoden überschreiben))Zusätzliche öffentliche Methoden in abgeleiteten Klassen?

Ist es außerdem akzeptabel, eine andere Konstruktormethodensignatur für jede abgeleitete Klasse zu haben?

+0

* EDIT * FYI, ich beziehe mich auf den Fall, wo Sie ein Objekt aus einer Fabrik konstruieren. Ich argumentiere, dass der aufrufende Code im Fall einer Fabrik wissen sollte, welche Methoden von abgeleiteten Klassen zu erwarten sind. –

Antwort

5

Persönlich sehe ich kein Problem mit beiden.

Wie für zusätzliche öffentliche Methoden auf abgeleitete Klassen:

Es gibt nur wenig Nutzen in diesem, in vielen Fällen. Die zusätzlichen Methoden können nicht verwendet werden, wenn die Klasse umgewandelt oder auf einen Verweis auf die Basisklasse gesetzt wurde, was die Nützlichkeit dieser Methode stark einschränkt. Abgesehen davon ist dieser Ansatz nicht besonders falsch. Unterklassen sollen spezifisches Verhalten hinzufügen - manchmal gibt es in einer Klassenhierarchie ein neues Verhalten in einer Unterklasse, das für die Basisklasse nicht geeignet ist. Wenn die Unterklasse häufig alleine verwendet wird, erscheint es durchaus sinnvoll, das zusätzliche Verhalten in den Methoden zu modellieren.

Was Konstruktor Signaturen -

Ich sehe kein Problem mit diesem auch nicht. Unterklassen benötigen oft mehr Informationen, um in einen brauchbaren Zustand versetzt zu werden als die abstrakte Klasse. Davon abgesehen stelle ich normalerweise sicher, dass ich jeden Konstruktor in der Basisklasse implementiere, und füge die neuen Parameter hinzu, die für die Unterklasse erforderlich sind.

Dass gesagt wird:

Es sei denn, es guter Grund ist, dass ich vermeiden würde eine Unterklasse Konstruktor mit weniger Parametern als die Basisklasse mit ... warum sollte ich in der Lage sein, etwas auf einem allgemeineren Fall zu spezifizieren und nicht der spezifische Fall? Ich finde, dass es normalerweise verwirrend ist, wenn Unterklassen völlig andere Konstruktionsoptionen haben als ihre Basisklassen.

+0

Wenn du ein Objekt aus einer Fabrik konstruierst, sag, dann habe ich Recht, dass es keine zusätzlichen öffentlichen Methoden geben sollte? Sollte nicht der Anrufcode im Fall einer Fabrik wissen, welche Methoden zu erwarten sind? –

+0

Es kommt darauf an - selbst wenn Sie aus einer Factory konstruieren, muss die Factory den Kompilierzeittyp des Objekts kennen (um den entsprechenden Konstruktor aufzurufen). Es kann über die zusätzlichen Parameter "wissen". In diesem Fall hängt es jedoch nur vom Szenario ab, wie es verwendet wird, etc. –

1

Es ist vollkommen akzeptabel, Ihren abgeleiteten Klassen zusätzliche öffentliche Methoden hinzuzufügen. Es ist auch völlig in Ordnung, ihnen verschiedene Konstruktoren zu geben. (In der Tat ist dies durchaus üblich.)

0

die abgeleiteten Klassen sollten keine zusätzliche öffentliche Methoden bieten

Kann ein Hund Dinge tun, dass ein Tier nicht?

Ist es außerdem akzeptabel, eine andere Konstruktormethodensignatur für jede abgeleitete Klasse zu haben?

Hier gibt es kein Problem. Abgeleitete Typen müssen nicht mit Konstruktorsignaturen ihrer Geschwister oder Eltern übereinstimmen.

+0

Um deine Frage zu beantworten, kann ein Hund Dinge tun, die manche Tiere nicht tun können ... wie Rinde, Beißen, Laufen, Schuppen, Springen, etc ... Würmer sind Tiere, (sie sind keine Pflanzen) - und Ein Wurm kann nichts davon tun ... –

2

Dies ist die Schönheit der abgeleiteten Klassen.

Während eine Pen-Klasse möglicherweise eine write() -Funktion hat, kann eine RetractablePen-Klasse, die Pen erweitert, möglicherweise auch eine Funktion "retractPoint()" aufweisen.

Wenn Sie eine Klasse erweitern, bedeutet dies - wörtlich - die Funktionalität davon zu erweitern.

+0

Wenn Sie ein Objekt aus einer Fabrik konstruieren, sagen Sie, dann habe ich Recht, dass es keine zusätzlichen öffentlichen Methoden geben sollte ? Sollte nicht der Anrufcode im Fall einer Fabrik wissen, welche Methoden zu erwarten sind? –

+0

Wenn Sie es aus einer Fabrik konstruieren, dann verwenden Sie wahrscheinlich Polymorphie und betrachten die Klasse als ob es nur ihre Eltern ist. In diesem Fall hätten Sie keinen Zugriff auf die Methoden, die in der untergeordneten Klasse definiert sind, es sei denn, Sie haben auf instanceof geprüft und sie umgesetzt. –

1

Nein, es ist vollkommen in Ordnung (und manchmal sehr notwendig von Entwurf), zusätzliche öffentliche Methoden hinzuzufügen. Betrachten Sie die (vollständig konstruierte) Situation einer abstrakten Basisklasse Shape, die eine Location-Komponente und eine Size-Methode aufweist. Wenn Sie beispielsweise Polygon von Shape ableiten, möchten Sie möglicherweise eine öffentliche Methode namens GetNumberOfSides() hinzufügen; aber das wollen Sie nicht haben, wenn Sie Circle von Shape ableiten.

Auf die gleiche Weise können die abgeleiteten Typen sehr unterschiedliche Konstruktionsanforderungen haben; Es ist nicht wirklich möglich zu wissen, was alle Anforderungen sein können, wenn Sie die abstrakte Basisklasse definieren. Sie können also unterschiedliche Signaturen verwenden. Nur weil Ihre dervied-Typen polymorph zur abstrakten Basisklasse sind, heißt das nicht, dass diese Basisklasse strenge Einschränkungen für die Implementierung der in dieser Basisklasse definierten Abstraktionen vorschreibt; Sie können es so ziemlich tun, wie Sie wollen.

2

Es ist in Ordnung im Allgemeinen.

Was Sie vermeiden möchten, ist die Verwendung der spezifischen in der generischen. d. h.

foreach(Animal a in myFarm.Animals) 
{ 
    a.Feed(); 
    // this is a bit grim 
    if(a is Horse) 
    { 
     ((Horse)a).CleanStable(); 
    } 
} 

Es ist also nicht der Akt des Hinzufügens der öffentlichen Methode, sondern eher, wo Sie sie aufrufen.

+0

Ich möchte ein Pferd, das seinen eigenen Stall säubert! Wo kann ich einen bekommen? ;) –

+0

Yeah ... Ich weiß ... ich schreibe während der Bauzeit, also habe ich keine Zeit, um so pedantisch zu sein, wie ich normalerweise bin ...: (... wird es tun.) – Quibblesome

0

Es ist nicht nur akzeptabel, es ist oft notwendig, dass die Konstruktoren anders sind. Zum Beispiel, wenn wir eine (unveränderliche) Rectangle Klasse haben und erweitern sie mit einem (unveränderlich) Square, sollte der Konstruktor von Square (Java zu verwenden, für den Moment)

public Square(double size) 

während des Konstruktor von Rectangle wäre

Was passiert, ist, dass der Unterklassenkonstruktor einen geeigneten Superklassenkonstruktor aufrufen sollte.

Als zusätzliche öffentliche Methoden kann es auf die Verwendung abhängen. Für den Square-Fall würde ich keine zusätzlichen Methoden hinzufügen. In Java gibt es jedoch eine Unterklasse PrintWriter von Writer , deren Zweck es ist, einige bequeme Methoden hinzuzufügen. In diesem Fall denke ich, dass es in Ordnung ist (Java hat sicherlich einige schlechte Beispiele, aber ich denke nicht, dass dies einer von ihnen ist). Ich würde auch die Möglichkeit einiger zusätzlicher Methoden für Container-/Unterarttypen erwarten.

Was Sie nicht tun sollten, ist die Super-Klassen-Methoden in einer Weise zu ändern, die die Erwartungen der Super-Klasse verletzt.

1

Wenn Sie die Liskov substitution principle respektieren, können Sie tun, was Sie wollen.

Natürlich fügen Sie eine Methode zu einer abgeleiteten Klasse nicht verletzt das Prinzip überhaupt.

Verwandte Themen