2012-07-21 4 views
5

Angenommen, wir haben eine abstrakte Klasse A und wir wollen alle Unterklassen zwingen, ein bestimmtes Feld zu haben. Dies ist in Java nicht möglich, da abstrakte Felder nicht definiert werden können.Wie kann man den Mangel an abstrakten Feldern in Java umgehen?

Problemumgehung 1: Erzwingen Sie Unterklassen, um eine Methode zu implementieren, die den gewünschten Wert liefert.

abstract class A { 
    abstract int getA(); 
} 

Drawback: Jede Unterklasse hat eine Methode für jedes abstraktes Feld implementieren wir haben wollen. Dies kann zu vielen Methodenimplementierungen führen.

Vorteil: Wir können die Methode getA in der abstrakten Klasse verwenden und implementieren Methoden mit ihm in A ohne sie in jeder Unterklasse zu implementieren. Der Wert hinter der Methode kann jedoch nicht von der abstrakten Klasse überschrieben werden.

Abhilfemaßnahme 2: die abstrakte Feld Simulieren der Unterklasse durch Erzwingen der abstrakten Klasse einen Wert zu geben.

abstract class A { 
    int a; 

    public A(int a) { 
    this.a = a; 
    } 
} 

Drawback: Wenn wir mehrere Felder (> 10), der Super-Konstruktoraufruf aussehen wird ein bisschen hässlich und verwirrend haben.

Vorteil: Wir können das Feld a in der abstrakten Klasse verwenden und implementieren Methoden mit ihm in A ohne sie in jeder Unterklasse zu implementieren. Außerdem kann der Wert a von der abstrakten Klasse überschrieben werden.

Frage: Welcher Workaround ist der übliche Weg, um das Ziel zu erreichen? Vielleicht gibt es einen besseren als die oben genannten?

+2

Fehle ich etwas? Warum geben Sie der abstrakten Klasse nicht einfach ein geschütztes * konkretes * Feld? Warum der Wunsch nach einem "abstrakten" Feld? Was ist ein abstraktes Feld? Was fehlt mir noch oder verstehe ich nicht? Übertreibe ich Ihr Problem zu sehr? Und welches Verhaltensproblem (nicht Codeproblem) versuchen Sie ohnehin zu lösen? –

+1

Oder Sie können eine Standardimplementierung von 'getA()' bereitstellen und sie einfach überschreiben, wo Sie einen anderen Wert wünschen. – Keppil

+0

_Warum_ wollen Sie alle Unterklassen zwingen, ein Feld zu haben? Das Problem ist in der Regel besser formuliert, um sie zu einem bestimmten Verhalten zu zwingen, das Sie nur mit Methodenspezifikationen durchführen. –

Antwort

0

Ich denke, opt.1 ist der Reiniger bei weitem. Ein paar Getter und Setter sind keine große Sache, und ich bezweifle, dass viele Anwendungsfälle mehr als nur ein paar abstrakte "Felder" haben.

Über opt.2, Sie vergessen, dass Konstruktoren nicht vererbt werden, und somit würden alle Unterklassen Konstruktoren in einer Weise implementiert werden, die a berücksichtigt.

1

Ich bevorzuge die erste. Ich liebe es nicht, Klassen in Fileds Namen zu koppeln, wie sie mit dem Status umgehen und wie sie ihn speichern. die erste ist näher an open/close principal

Ich empfehle Vererbung zu vermeiden. Vererbung ist sehr frustrierend und schwer zu pflegen. erinnere mich an effektive Java-Beratung - bevorzuge Zusammensetzung andere Vererbung

2

Die abstrakte Methode ist wahrscheinlich am objektorientiertesten.

Wenn Sie zu viele Felder haben, können Sie diese in einem POJO neu gruppieren (wenn ein neues Konzept angemessen ist).

+1

nice feature ist, dass eine gar nicht existiert: int getA() {return 4;} if property a immer 4 für die Unterklasse oder getA() {return b + c;} wenn es von anderen Feldern abhängt. – josefx

+0

Machen Sie es zu einer generischen Methode und es könnte nicht nur nicht existieren, es ist vielleicht noch nicht vorhanden. –

0

Problemumgehung 2 ist sehr häufig wegen 2 Vorteile:

1) diejenige, die Sie erwähnt - das Feld gehört nicht zu der Unterklasse - es gehört zu den Eltern, und das ist wichtig, weil es war „forderte“ durch das übergeordnete Element und weil das übergeordnete Element es verwenden kann

2) Bei der Unterklassierung vom übergeordneten Objekt sind Sie sich dieses Feldes sehr bewusst, da Sie es bei der Implementierung des Konstruktors weitergeben müssen. Wenn ich die erste Problemumgehung sehen würde, wüsste ich nicht, was ich daraus verstehen soll. Auf diese Weise verstehe ich, dass die Elternklasse dieses Feld zum Funktionieren braucht, also muss es einen bedeutungsvollen Wert haben.

Hinweis: Wenn Sie eine Klasse mit 10 Feldern haben, die initialisiert werden müssen, liegt wahrscheinlich etwas falsch in Ihrem Design.

0

1. Eigentlich ist es nicht zu wissen, was man will, aber es geht um die Flexibilität und die Fähigkeit, Veränderungen anzupassen.

2. Es ist immer besser zu Encapsulate Behaviours, die sich ständig ändert, entweder in eine Schnittstelle oder eine abstrakte Klasse.

3. Sie 1. Abhilfe wird an Orten gut sein, wo Sie andere Implementierung für das gleiche Verhalten müssen in verschiedenen Klassen. Dann an diesem Ort wird entweder eine Schnittstelle oder Ihre 1. Abhilfe wird eine gute Wahl sein.

ZB:

Betrachten Painting als Klasse mit paint() Methode.

Jetzt

paint() Methode kann Streicheln haben, gleiten, Schattierung usw. Arten, es zu tun.

Dann ist es besser, diese Methode in eine abstrakte Klasse oder ein Interface zu verkapseln.

public interface Paint{ 

paintDoIt(String style); 

} 

4. Ihre 2. Wordaround wird an einem Ort gut sein, wo Sie bestimmte Verhaltensweisen wollen, müssen durch die Unterklasse implementiert sein.

ZB:

Betrachten Auto als abstrakte Klasse, jetzt to be car seine sehr wichtig, dass es einen Lenkungs haben muss, 4 Räder, Motor, etc. Also diese Funktionen umgesetzt werden müssen.

wo wie andere Funktionen wie Musiksystem, LCD, etc. sind optional und hängt vom Autotyp ab.

Verwandte Themen