Eine Standardlösung, um if/else-Ketten in solchen Situationen zu vermeiden, besteht darin, die Klassen eine Schnittstelle implementieren zu lassen, die eine Methode enthält, mit der die Objekte selbst wissen, was sie zu tun haben - d.h. die Vererbung zu verwenden, wie Sie vorschlagen.
Die konkreten Klassen kennen ihre eigenen konkreten Typen, wissen, wie sie sich selbst kopieren können usw., aber in der Schleife weiß man das nicht - daher ist es sinnvoll, die Verantwortung für die Erstellung neuer konkreter Klassen auf die konkreten Klassen selbst zu übertragen.
Was ich tun würde, ist, eine neue Methode in die Y
Schnittstelle, die die neue Instanz erzeugt. Wenn du zum Beispiel nur eine Kopie der Instanzen in der Liste haben willst, könntest du eine "copy" Factory-Methode hinzufügen zu Y
:
public interface Y {
...
public Y copy();
...
}
Jede Implementierung von Y
muss die Kopiermethode implementieren. Sie weiß, wie sie sich selbst kopieren kann. Beispiel:
public class MyClass implements Y {
...
public MyClass copy() {
return new MyClass(...);
}
...
}
Die Erstellung neuer Instanzen bei der Iteration durch die Liste läuft dann einfach wie folgt ab:
List<Y> ys = ...get list from somewhere...;
for (Y y : ys) {
Y copy = y.copy();
...
}
Beachten Sie, dass bei diesem Ansatz keine Reflexion oder andere Hacks erforderlich sind.
Beachten Sie auch, dass die Schleife nichts über die konkreten Klassen wissen muss - sie muss nur die Schnittstelle kennen Y
. Der gesamte für die konkreten Klassen spezifische Code ist in den konkreten Klassen selbst enthalten. Dies macht den Code, der sie verwendet, einfacher (vermeidet die instanceof + if/else-Ketten).
Anstelle einer Kopiermethode könnten Sie natürlich auch fortgeschrittenere Methoden erstellen, die vielleicht einige Parameter benötigen. Dies könnte nützlich sein, wenn die Objekte nicht nur sich selbst kopieren müssen, sondern die neue Instanz von sich selbst auf eine spezielle Art und Weise basierend auf einer Eingabe erstellen müssen.
(Hinweis: Diese Kopiermethode erinnert vielleicht an "clone", aber da clone in Java ziemlich kaputt ist, ist dies normalerweise ein besserer Ansatz)
Anmerkung: Ich habe angenommen, dass sowohl die Ai'
Wrapper und Ai
erweitert Y
.
Hinweis: Wenn Sie keine Änderungen an Y
aber die Adapterklassen ändern können, können Sie eine neue Schnittstelle erstellen Y'
die die Y
und die die Adapter-Klassen implementieren, und verwenden eine List<Y'>
代わりに List<Y>
über die Sie in der Schleife iterieren.