Dire que j'ai la configuration suivante:collection de retour du même paramètre en tant que paramètre de collecte d'entrée
abstract class AbstractBaseClass {
// Some common attributes
AbstractBaseClass() { }
AbstractBaseClass(AbstractBaseClass orig) {
// Copy ctor impl
}
protected abstract AbstractBaseClass clone();
}
class DerivedClassA extends AbstractBaseClass {
// Some specialized attributes
DerivedClassA() { }
DerivedClassA(DerivedClassA orig) {
super(orig);
// Copy ctor impl
}
List<DerivedClassB> subObjects = new ArrayList<>();
protected DerivedClassA clone() {
return new DerivedClassA(this);
}
}
class DerivedClassB extends AbstractBaseClass {
// Some specialized attributes
DerivedClassB() { }
DerivedClassB(DerivedClassB orig) {
super(orig);
// Copy ctor impl
}
List<DerivedClassC> subObjects = new ArrayList<>();
protected DerivedClassB clone() {
return new DerivedClassB(this);
}
}
// DerivedClassC implemented the same way
J'aimerais maintenant mettre en œuvre une méthode générique dans ma classe abstraite de base qui clones une liste donnée de sujets contenus dans l'une des classes dérivées:
abstract class AbstractBaseClass {
// Other stuff, see above
// Doesn't work because of type issues
protected <T> List<T> cloneList(List<? extends AbstractBaseClass> origList) {
if (origList == null) return null;
List<T> result = new ArrayList<>();
for (AbstractBaseClass i: origList) {
result.add(i.clone());
}
return result;
}
}
maintenant, je veux appeler cette méthode comme suit:
class DerivedClassA extends AbstractBaseClass {
// Other stuff
List<DerivedClassB> subObjects;
DerivedClassA(DerivedClassA orig) {
super(orig);
// Copy ctor impl
subObjects = cloneList(orig.subObjects);
}
}
Maintenant, ce que je m'attendais à ce que l'implémentation de cloneList(...)
dans AbstractBaseClass
renvoie une liste qui a le même type que la liste d'arguments, donc je peux les stocker dans mes classes dérivées. Comment pourrais-je m'y prendre?
Ce que j'ai trouvé à ce jour est que je peux mettre en œuvre cloneList(...)
comme ceci:
protected List<AbstractBaseClass> cloneList(List<? extends AbstractBaseClass> origList) {
// null check...
List<AbstractBaseClass> result = new ArrayList<>();
for (AbstractBaseClass i: origList) {
result.add(i.clone());
}
return result;
}
et ensuite utiliser des moulages dans mes classes dérivées:
DerivedClassA(DerivedClassA orig) {
super(orig);
// Copy ctor impl
List<AbstractBaseClass> tmp = cloneList(orig.subObjects);
for (DerivedClassA i: tmp) {
subObjects.add((DerivedClassA) i);
}
}
Mais ce n'est pas vraiment satisfaisant pour moi, puisque je voudrais avoir une implémentation générique qui ne repose pas sur le cast après avoir obtenu ma collection clonée d'objets de type AbstractBaseClass
comme vous voulez une implémentation 'générique', les génériques pourraient nous valoir un coup d'oeil – Stultuske
vérifiez cette page: https://docs.oracle.com/javase/tutorial/java/generics/index.html –
* Soyez conscient * " La structure clone souffre de sérieuses failles de conception "http://bugs.java.com/bugdatabase/view_bug.do?bug_id=4220218 –