OVH Cloud OVH Cloud

Types, génériques et reconstruction

4 réponses
Avatar
Wamli
Bonjour,

J'utilise dans un projet une classe prinicpale nommée "AbstractGraph",
abstraite. Elle dispose de plusieurs implémentations mais lors du traitement
les objets sont généralement utilisé sous leur type "AbstractGraph" et non
sous leur type propre.

Lors d'une lecture d'information externes, un abstractGraph est reconstruit
mais en utilisant une implémentation vide (DefaultGraphImpl), ne permettant
que d'accéder aux fonctions de la classe principale. Par contre, plus tard,
selon les besoin, une reconstruction plus pointue de l'objet peut s'avérer
nécessaire et c'est la que se pose mon problème. Pour résumer :

public void export() {
AbstractGraph graph = new MonGraph(); // Mon Graph est une
implémentation possible
graph.write(out);
}

public void import() {
AbstractGraph graph = AbstractGraph.read(in); // La classe
DefaultGraphImpl est utilisée

// en interne pour reconstruire le graph

....
if (condition_quelconque) {
// on a soudain besoin d'avoir accès à l'objet sous sa forme
"MonGraph", les fonctions disponibles
// dans AbstractGraph ne suffisant pas. L'idée serait de pouvoir
"caster" le graph dans le type
// voulu. Mais un cast "java style" ne fonctionne pas.
MonGraph monGraph = (MonGraph)graph;
}
}

Une solution possible serait de munir toute les implémentation de la classe
AbstractGraph d'un constructeur utilisant comme paramètre un
"DefaultGraphImpl". Mais cela reviendrait à instancier deux objets disctints
et à devoir recopier le contenu de l'un sur l'autre. De plus, cela oblige à
écrire ce fameux constructeur pour chaque implémentation--> travail
supplémentaire.

Je cherche une solution "dynamique", peut-être en forçant java à reconnaître
un type différent ou je ne sais pas.

Quelqu'un a-t-il une idée ?

4 réponses

Avatar
obere
Est ce que tu peux utiliser la serialization pour faire tes write() et
read() ?

Avec la serilization, la classe de l'objet serait sauvegardee entre le
write() et le read() et ton cast marcherait ...
Avatar
remy

peut etre et encore il faut voir

public interface Zone
{
public void SetImg(BufferedImage image);
public void add(Cible c);
}
public class ZoneJeuImg extends JPanel implements Zone
{
....
public void test()
{
....
}
}
public class ZoneJeuText extends JPanel implements Zone
{
...
public void test1()
{
....
}
}

...

public void add(Zone s)
{
if(s instanceof ZoneJeuText )
{
s.test1();
}
if(s instanceof ZoneJeuImg )
{
s.test();
}

}

--
des conneries j'en ai dites oui oui je vous assure...
mais elles n'engagent que votre perception
remy
Avatar
Syrion


peut etre et encore il faut voir

public interface Zone
{
public void SetImg(BufferedImage image);
public void add(Cible c);
}
public class ZoneJeuImg extends JPanel implements Zone
{
....
public void test()
{
....
}
}
public class ZoneJeuText extends JPanel implements Zone
{
...
public void test1()
{
....
}
}

...

public void add(Zone s)
{
//ici c'est inutile ce que tu fais : met la méthode test() dans ton

interface Zone et redéfinit là dirérament dans les 2 classes EoneJeuText
et ZoneJeuImg. ensuite, dans cette méthode fais s.test() et suivant le
type réel de Zone, la bonne méthode sera exécutée automatiquement
if(s instanceof ZoneJeuText )
{
s.test1();
}
if(s instanceof ZoneJeuImg )
{
s.test();
}

}



Avatar
remy
ce que j'ai compris de son pb
c'est qu'il ne veut pas se compliquer la vie en utilisant un type
generique dans son code et qu'il ne veut pas justement tout mettre
dans le type generique exemple

public Object add(Object s,Object s1)
{
if(s instanceof JComponent )
{
((JComponent)s).add(s1);
}
if(s instanceof String )
{
(String)s=(String)s+" coucou "+(String)s1;

}
return s;
}


--
des conneries j'en ai dites oui oui je vous assure...
mais elles n'engagent que votre perception
remy