2016-06-29 14 views
2

Ich experimentierte mit der Herstellung einiger einfacher Swing Klassen und ich stolperte über eine Frage darüber, wie ich Aufrufe von Methoden, die in konkreten Klassen implementierten abstrakten Klassen implementiert werden sollten.Wie man Java abstrakte Klassenhierarchie und polymorphe Methodenaufruf und -definition anordnet

Zur Zeit habe ich die oberste Eltern einer kleinen Hierarchie von abstrakten Klassen und konkreten Klassen, die die abstrakte (auf der obersten und zweiten Ebene) addComponents() Methode der Klassen, die als die Kinder dieser Hierarchie beabsichtigt sind. Dies stellte eine Abfrage dar, wo man eine solche Methode definieren und aufrufen sollte, da die Absicht darin bestand, die Definition einer solchen Methode innerhalb der Klassen zu platzieren, die die Kinder der Hierarchie erweitern.

Die Hierarchie ist wie folgt:

public abstract class AbstractFieldPanel extends JPanel 

public abstract class BorderedFieldPanel extends AbstractFieldPanel 

public class ExampleDataPanel extends BorderedFieldPanel 

public class FieldPanel extends AbstractFieldPanel 

würde Ich mag die Details angeben, welche Komponenten in den Klassen hinzugefügt werden, die BorderedFieldPanel und AbstractFieldPanel bei der Umsetzung der zuvor abstract addComponents() Verfahren verlängern.

Der Aufruf des addComponents() Mehtod ist somit abstract wo es in BorderedFieldPanel und AbstractFieldPanel definiert ist. Die konkreten Implementierungen der addComponents() Methode befinden sich in den ExampleDataPanel und FieldPanel, die die beabsichtigten Instanzen ihrer Verwendung waren. Die Frage, die ich habe, ist, ob ich unter polymorphe Gründe recht hatte, den Aufruf an die abstrakten Methoden im Konstruktor der höchsten Klasse in der Hierarchie AbstractFieldPanel zu setzen, oder ob er vom Konstruktor der niedrigsten Klasse aufgerufen werden sollte in der Hierarchie?

Ich nahm zunächst an, dass dies gut ist OO Design, unter Ausnutzung der Vererbung und der polymorphen Eigenschaften und Delegation von abstrakten Klassen.

Wenn dies jedoch richtig ist, muss dies (in einigen Fällen) Probleme verursachen, wenn man bedenkt, dass der super()-Konstruktor explizit oder implizit in der ersten Zeile der extending-Klassen aufgerufen wird. Es ist also irgendwie nicht unbedingt das Richtige, was man unter Designgesichtspunkten tun kann, und ich habe gehofft, um Rat zu fragen, wie man das am besten angehen sollte.

+0

Das Aufrufen von überschreibbaren Methoden aus einem Konstruktor ist keine gute Idee: Die Methode in der Unterklasse wird für ein Objekt aufgerufen, das noch nicht konstruiert ist. –

+0

danke, obwohl es aus ähnlichen Gründen falsch klang. – manOf

+0

Kann mir vielleicht jemand sagen, wie ich es neu gestalten soll? Alle diese Klassen müssen diese Methode aufrufen. Da es sich um Methoden handelt, die sich auf die Zusammensetzung des Objekts beziehen, bin ich ein wenig verwirrt, da ich erwarten würde, dass dies ein Verhalten ist, das innerhalb eines Konstruktors innerhalb der Hierarchie aufgerufen wird. – manOf

Antwort

0

Wenn Sie sicherstellen möchten, dass diese Komponenten beim Erstellen des Objekts hinzugefügt werden, können Sie sie im Konstruktor AbstractFieldPanel als Argument verwenden (anstelle eines Konstruktors ohne Argumente). Das würde bedeuten, dass die Unterklassenkonstruktoren super(components) aufrufen müssen, indem sie eine Sammlung von Komponentenobjekten an den Superklassenkonstruktor übergeben. Dann würde AbstractFieldPanel tatsächlich die Komponenten hinzufügen, die ihm gegeben wurden.

0

Da ich Zusammensetzung über Vererbung bevorzugen würde, warum nicht eine Schnittstelle, die addComponents() enthält und haben Ihre konkrete Klassen implementieren das?

Warnung, persönliche Meinung
Abstrakte Klassen sind (für mich) ein Codegeruch, da sie meistens verwendet wird Code DRY in Subklassen zu halten, künstliche, nicht-funktionellen Klassen zu schaffen ("was ist der Zweck dieser Klasse ist, was tut es? Eine abstrakte Klasse tut nichts, kann nichts tun, da es nicht vollständig ist.Schwieriger zu testen, führt zu doppelten Tests (Methoden werden von allen Unterklassen getestet und nicht nur einmal). Natürlich gibt es Fälle, in denen es tatsächlich nützlich ist, aber ich bevorzuge lose gekoppelten Code, so dass es einfacher ist zu testen.