OVH Cloud OVH Cloud

Spécialisation classe abstraites - Plug-in

12 réponses
Avatar
Jean-Philippe Martin
Bonjour,

j'ai créer un éditeur générique que l'on peut spécialiser en spécifiant des
classes abstraites.

Comment puis-je créer un petit menu déroulant qui me proposerait de charger
telle ou telle classes spécifiant la classe abstraite avant de lancer
l'éditeur ?

Pour être plus clair, imaginer une classe abstraite HelloWorldAbstract.class
avec un methode abstraite SaySomething() qui afficherait a l'écran une
phrase quelconque. J'aimerais pouvoir étendre HelloWorldAbstract.class en
plusieurs classes différentes et les placer dans un répertoire "plug in" par
exemple. Comment puis-je créer un petit menu déroulant me permettant de
choisir au démarrage la classe que je souhaite utiliser pour affichier une
phrase a l'écran ?

Voilà j'espere avoir été clair.

ps: L'aide à m'apporter ne consiste pas dans la création du gui.

Bien à vous, Jean-Philippe.

10 réponses

1 2
Avatar
Nico
Si j'ai bien compris, tu veux la liste de tes classes dérivées de
HelloWorldAbstract.class.
Si c'est bien çà, voilà un exemple :
http://cvs.sourceforge.net/viewcvs.py/genj/dev/src/core/genj/report/ReportLoader.java?view=markup
Il s'agit d'un bout d'une appli de généalogie. Pour la génération de
rapports, il y a une classe de base Report qui est dérivée pour chaque
rapport.
La classe ReportLoader ci-dessus permet d'obtenir toutes les classes
dérivées.

Nico

"Jean-Philippe Martin" a écrit dans le
message de news:411b58a5$0$292$
Bonjour,

j'ai créer un éditeur générique que l'on peut spécialiser en spécifiant
des

classes abstraites.

Comment puis-je créer un petit menu déroulant qui me proposerait de
charger

telle ou telle classes spécifiant la classe abstraite avant de lancer
l'éditeur ?

Pour être plus clair, imaginer une classe abstraite
HelloWorldAbstract.class

avec un methode abstraite SaySomething() qui afficherait a l'écran une
phrase quelconque. J'aimerais pouvoir étendre HelloWorldAbstract.class en
plusieurs classes différentes et les placer dans un répertoire "plug in"
par

exemple. Comment puis-je créer un petit menu déroulant me permettant de
choisir au démarrage la classe que je souhaite utiliser pour affichier une
phrase a l'écran ?

Voilà j'espere avoir été clair.

ps: L'aide à m'apporter ne consiste pas dans la création du gui.

Bien à vous, Jean-Philippe.




Avatar
Jean-Philippe Martin
Si j'ai bien compris, tu veux la liste de tes classes dérivées de
HelloWorldAbstract.class.
Si c'est bien çà, voilà un exemple :

http://cvs.sourceforge.net/viewcvs.py/genj/dev/src/core/genj/report/ReportLoader.java?view=markup

Il s'agit d'un bout d'une appli de généalogie. Pour la génération de
rapports, il y a une classe de base Report qui est dérivée pour chaque
rapport.
La classe ReportLoader ci-dessus permet d'obtenir toutes les classes
dérivées.

Nico



Je suis déjà content que quelqu'un ai compris :o)

J'ai essayé de comprendre le code et j'ai un petit problème ici:

Report r = (Report)cl.loadClass(rname).newInstance();

Ma classe qui joue le meme role que Report est abstraite, je ne peux donc
utiliser la méthode newInstance(), sinon j'obtient une exception de type
InstantiationException.

Comment faire pour lui faire charger une classe dont le type n'est pas connu
a l'avance, vu que c'est le but du loader ici. :os

Est-ce clair ?

Merci d'avance, et merci tout court deja a Nico.

Avatar
Nico
En fait, dans la ligne de code que tu donnes, le "rname" est le nom de la
classe dérivée.
La ligne charge la classe "rname" en mémoire et l'initialise (c'est le
loadclass), puis ensuite on en crée une instance (newInstance) que l'on
caste ensuite vers la classe de base.

Dans ton cas :
HelloWorldAbstactClass c = (HelloWorldAbstactClass)
cl.loadClass("HelloWorldDerivee").newInstance();
devrait marcher.

"Jean-Philippe Martin" a écrit dans le
message de news:411b793b$0$295$

J'ai essayé de comprendre le code et j'ai un petit problème ici:

Report r = (Report)cl.loadClass(rname).newInstance();

Ma classe qui joue le meme role que Report est abstraite, je ne peux donc
utiliser la méthode newInstance(), sinon j'obtient une exception de type
InstantiationException.

Comment faire pour lui faire charger une classe dont le type n'est pas
connu

a l'avance, vu que c'est le but du loader ici. :os

Est-ce clair ?

Merci d'avance, et merci tout court deja a Nico.




Avatar
Jean-Philippe Martin
"Nico" a écrit dans le message de
news:411b7dbc$0$314$
En fait, dans la ligne de code que tu donnes, le "rname" est le nom de la
classe dérivée.
La ligne charge la classe "rname" en mémoire et l'initialise (c'est le
loadclass), puis ensuite on en crée une instance (newInstance) que l'on
caste ensuite vers la classe de base.

Dans ton cas :
HelloWorldAbstactClass c = (HelloWorldAbstactClass)
cl.loadClass("HelloWorldDerivee").newInstance();
devrait marcher.



C'est justement là qu'il m'envoie bouler :o(

java.lang.InstantiationException: plug.NFRFramework

at java.lang.Class.newInstance0(Unknown Source)

at java.lang.Class.newInstance(Unknown Source)

at editor.FrameworkLoader.<init>(FrameworkLoader.java:102)



où plug.NFRFramework représente une classe Dérivée (dans le package plug) de
AbstractHelloWorld



:o(

Avatar
Jean-Philippe Martin
En fait, dans la ligne de code que tu donnes, le "rname" est le nom de la
classe dérivée.
La ligne charge la classe "rname" en mémoire et l'initialise (c'est le
loadclass), puis ensuite on en crée une instance (newInstance) que l'on
caste ensuite vers la classe de base.

Dans ton cas :
HelloWorldAbstactClass c = (HelloWorldAbstactClass)
cl.loadClass("HelloWorldDerivee").newInstance();
devrait marcher.


Je rappelle (comme le montre son nom) que HelloWorldAbstactClass est
abstraite et que donc, on ne peut l'instancier directement.

On devrait plutot pouvoir faire

HelloWorldDerivee c = (HelloWorldDerivee)
cl.loadClass("HelloWorldDerivee").newInstance();

non ?

Avatar
no.bcausse.spam
Jean-Philippe Martin wrote:

Je rappelle (comme le montre son nom) que HelloWorldAbstactClass est
abstraite et que donc, on ne peut l'instancier directement.

On devrait plutot pouvoir faire

HelloWorldDerivee c = (HelloWorldDerivee)
cl.loadClass("HelloWorldDerivee").newInstance();


un petit probleme de priorité?

HelloWorldDerivee c = (HelloWorldDerivee)(
cl.loadClass("HelloWorldDerivee").newInstance());

--
bruno Causse
http://perso.wanadoo.fr/othello

Avatar
Jean-Philippe Martin

un petit probleme de priorité?

HelloWorldDerivee c = (HelloWorldDerivee)(
cl.loadClass("HelloWorldDerivee").newInstance());



Ben non le probleme est que je le type HelloWorldDerivee n'est pas connu à
l'avance, et varie en fonction du contenu du repertoire de classes.

HelloWorldDerivee c = (HelloWorldDerivee)
cl.loadClass("HelloWorldDerivee").newInstance() ne posera pas de probleme a
mon avis. Le probleme par contre est que je ne peux pas me permettre un tel
cast car "HelloWorldDerivee" varie.

On pourrait faire comme proposée par Nico en HelloWorldAbstractClass c (HelloWorldAbstractClass) cl.loadClass("HelloWorldDerivee").newInstance()
mais a ce moment je ne peux instancier car il me dit que j'essaye
d'instancier une classe abstraite :os

Avatar
Jean-Philippe Martin
Dans ton cas :
HelloWorldAbstactClass c = (HelloWorldAbstactClass)
cl.loadClass("HelloWorldDerivee").newInstance();
devrait marcher.



Je pense avoir trouve un problème :o)

ma classe Abstraite HelloWorldAbstractClass n'a pas de constructueur sans
paramètre. Les classes qui l'étende non plus !

Si j'applique la methode newInstance() sur une classe dérivée alors Java
essaye d'instanciée la classe Abstraite ! Il me faudrait donc un moyen
d'instancier la classe avec un parametre. Mettre un parametre dans
newInstance() en gros.

Est-ce faisalbe ?

Avatar
Emmanuel Feller
La réponse était dans le post mais Bruno n'a pas fait attention à reprendre
tes noms de classes.

Il manque en effet des parenthèses autour de l'instanciation, ce qui fait
que c'est le résultat de cl.loadClass("HelloWorldDerivee")
qui est casté et pas celui de
cl.loadClass("HelloWorldDerivee").newInstance().

Il faut donc écrire :
HelloWorldAbstractClass c (HelloWorldAbstractClass)
(cl.loadClass("HelloWorldDerivee").newInstance());

Et la ca marche, j'ai retesté pour etre bien sûr.
Emmanuel

"Jean-Philippe Martin" a écrit dans le
message de news:411b9410$0$313$

un petit probleme de priorité?

HelloWorldDerivee c = (HelloWorldDerivee)(
cl.loadClass("HelloWorldDerivee").newInstance());



Ben non le probleme est que je le type HelloWorldDerivee n'est pas connu à
l'avance, et varie en fonction du contenu du repertoire de classes.

HelloWorldDerivee c = (HelloWorldDerivee)
cl.loadClass("HelloWorldDerivee").newInstance() ne posera pas de probleme
a

mon avis. Le probleme par contre est que je ne peux pas me permettre un
tel

cast car "HelloWorldDerivee" varie.

On pourrait faire comme proposée par Nico en HelloWorldAbstractClass c > (HelloWorldAbstractClass) cl.loadClass("HelloWorldDerivee").newInstance()
mais a ce moment je ne peux instancier car il me dit que j'essaye
d'instancier une classe abstraite :os





Avatar
Jean-Philippe Martin
La réponse était dans le post mais Bruno n'a pas fait attention à
reprendre

tes noms de classes.

Il manque en effet des parenthèses autour de l'instanciation, ce qui fait
que c'est le résultat de cl.loadClass("HelloWorldDerivee")
qui est casté et pas celui de
cl.loadClass("HelloWorldDerivee").newInstance().

Il faut donc écrire :
HelloWorldAbstractClass c > (HelloWorldAbstractClass)
(cl.loadClass("HelloWorldDerivee").newInstance());

Et la ca marche, j'ai retesté pour etre bien sûr.
Emmanuel



J'apprécie grandement l'aide que vous tentez de m'apporter. Toutefois, je
pense que l'erreur qu'il susbsiste est dûe au fait que ma classe
"HelloWorldAbstractClass" ne possède pas de constructeur par défaut comme
expliqué dans mon dernier post.

Est-ce que ceci n'ajoute pas de piment au problème ? :o)

1 2