Bon allez je tente d'expliquer. Pas de code, c'est trop complexe pour ce que je veux faire
Alors d'un côté j'ai trois classes A (qui est abstraite), B et C. B et C héritent de A.
De l'autre, j'ai trois classes Alpha (abstraite), Beta et Gamma. Beta et Gamma héritent de Alpha.
La classe A possède un attribut de type Alpha (on va l'appeler alpha en minuscule). Je veux que dans ma classe B, cet attribut soit explicitement de type Beta et que dans la classe C il soit explicitement de type Gamma car Beta et Gamma contiennent des méthodes spécifiques. Et je ne veux pas faire de cast car c'est dégueulasse.
J'ai tenté plusieurs trucs qui ne marchent pas (je le savais avant de le faire cependant).
Solution 1
Constructeur de B :
B() {
....alpha = new Beta();
}
Constructeur de C :
C() {
....alpha = new Gamma();
}
Cette solution marche mais je suis obligé de faire un cast à chaque fois que je veux utiliser les méthodes spécifiques de mon objet alpha.
Solution 2 :
A base de type génériques. Je modifie ma déclaration de A comme suit :
public abstract class A<T extends Alpha> {
....private T alpha;
}
et mes classes B et C comme suit (j'écris juste B car pour C c'est équivalent) :
public class B extends A<Beta> {
....public B() {
........alpha = new Beta();
....}
}
Ca marche mais je suis obligé d'initialiser alpha dans les sous-classes, ce qui est relativement très beaucoup crade. Sachant qu'on a le type générique, je pourrais faire ça dans la super classe comme suit :
public A() {
....alpha = new T();
}
Problème... Java introduit un effaçage des type (type erasure) à la compilation, du coup impossible de faire un new T(); car T n'existe pas dans le bytecode
Solution 3 :
On garde la même structure que dans la solution 2 mais on ajoute ce constructeur dans A :
protected A(Class<T> clazz) {
....alpha = clazz.newInstance();
}
et on définit les constructeurs B et C comme suit :
public B() {
....super(Beta.class);
}
D'une, c'est monstrueusement crade, et de deux ça marche pas
Des idées ? Je n'oblige pas à garder la structure actuelle (à mon avis c'est impossible) donc si vous voyez un pattern applicable 