Wie würden Sie einen Kopierkonstruktor für eine Klasse mit Interface-Member-Variablen schreiben?
Zum Beispiel:
%Vor% Muss ich eine konkrete Animal
haben? Wenn ja, scheint es, als würde die Klasse für Häuser mit Hunden vs. Häuser mit Katzen wieder verworren!
Sie haben eine von drei Möglichkeiten:
IAnimal
, um das Objekt tief zu klonen (wird von Bibliotheken wie den DOM-Schnittstellen verwendet, z. B. Node.cloneNode(boolean)
) IAnimal
einen Kopierkonstruktor, der den konkreten Typ annimmt und dies im Schnittstellenvertrag als Voraussetzung festlegt, und verwenden Sie dann reflection, um darauf zuzugreifen Serializable
-Klassen usw., wie die aufgeführten hier
Kopiermethode
Für # 1 machen Sie etwas wie:
%Vor%Implementieren Sie das in Ihren konkreten Typen und rufen Sie dann diese Methode auf, um es zu kopieren:
%Vor%Dokumentieren Sie dann die Anforderung in der Schnittstelle und sagen Sie etwas wie folgt aus:
Implementierungen dieser Schnittstelle müssen ein Objekt, das nicht
==
ist, an diese Instanz zurückgeben und müssen tief geklont werden, damit die Manipulation dieses Objekts nicht zur Manipulation des zurückgegebenen Objekts und umgekehrt führt versa.
Implementierungen müssen diesem Vertrag folgen, um mit der Schnittstelle kompatibel zu sein, aber dies wird zur Kompilierzeit nicht erzwungen.
Konstruktor kopieren
Versuchen Sie, reflektiv auf einen Kopierkonstruktor zuzugreifen, und geben Sie an, dass ein Kopierkonstruktor in allen konkreten Implementierungen in der Schnittstelle erforderlich ist, der Teil des Schnittstellenvertrags wird. Jede Implementierung würde dann so aussehen:
%Vor%Und dann brauchen Sie nur eine einzige Methode, um jede Implementierung zu kopieren:
%Vor%Wenn Sie dies haben, fügen Sie in der Dokumentation Ihrer Schnittstelle eine entsprechende Anweisung hinzu:
Implementierungen dieser Schnittstelle müssen einen Kopierkonstruktor definieren, der ein Argument des gleichen Typs oder Supertyps ihrer Klasse akzeptiert. Dieser Konstruktor muss eine tiefe Kopie des Arguments erstellen, damit die Manipulation dieses Objekts nicht zur Manipulation des zurückgegebenen Objekts führt und umgekehrt.
Auch dies wird durch die Laufzeit erzwungen. Die obige copy
-Methode löst NoSuchMethodException
-Fehler aus, wenn der Konstruktor nicht existiert.
Kopierwerk
Dies nimmt die IAnimal
und verwendet instanceof
, um zu entscheiden, an welche Methode es übergeben werden soll, wie:
Führen Sie dann das tiefe Kopieren in den copy
-Methoden für jeden Typ manuell durch.
Wenn ich Ihr Problem verstehe, da Sie Konstruktoren in einer Schnittstelle nicht angeben können, müssten Sie eine deep-copy-Methode in Ihrer Schnittstelle deklarieren und sie in Ihren Klassen implementieren. Sie können eine Schnittstelle nicht instanziieren. Sie möchten möglicherweise auch etwas in House
genau nach Ihren Bedürfnissen kopieren.
Das Problem ist natürlich, dass es an dir liegt, etwas falsch zu machen. Es riecht irgendwie, als würde man hier nicht wirklich eine Schnittstelle wollen, sondern eine abstrakte Klasse.
ok, lassen Sie mich ein Problem in diesem Code erklären. Beachten Sie, dass Sie, wenn Sie eine Schnittstelle haben, ein Verhalten definieren, nicht eine Abstraktion oder Identität eines Objekts (oder einer Kreatur) wie eines Tieres. In diesem Fall benötigen Sie eine abstrakte Klasse anstelle einer Schnittstelle. das begann gesagt. Sie können keinen Konstruktor auf einer Schnittstelle haben (siehe Warum dürfen wir keinen Konstruktor in einer Schnittstelle angeben? ), daher kann die Verwendung einer Schnittstelle auf diese Weise fehlschlagen.
In diesem Fall würde ich stattdessen eine abstrakte Klasse vorschlagen:
%Vor%Nach meinem Wissen gibt es in Java keine direkte Entsprechung dazu.
Der "richtige" Weg ist, das Interface selbst zu implementieren Cloanable .
Und der einfachste Weg könnte sein, Reflektion zu verwenden. Ich weiß, dass es eine Bibliothek gibt, die tiefe Kopien von beliebigen Objekten behandelt, aber ich kann mich im Moment nicht an den Namen erinnern.
Related: Java: empfohlene Lösung für tiefes Klonen / Kopieren eine Instanz
Tags und Links java interface copy-constructor member-variables