Faire passer une donnée membre en paramètre ?

Faire passer une donnée membre en paramètre ? - Java - Programmation

Marsh Posté le 26-10-2004 à 15:28:13    

Bonjour !
 
Voici un pb que j'ai souvent eu en C, et maintenant que je passe en java je retombe dessus. En gros ce que je veux faire se rapporte à :
 
public Class CObjet
{
int ID;
str name;
str propriétaire;
...
 
void afficher(??? critère)
{
system.out.println(objet.critère);
}
}
 
Ne pas se formaliser sur les détails, le pb est le suivant : comment faire passer une donnée membre en paramètre ?
 
Dans mon problème réel, ça peut même etre une donnée membre qui n'appartient pas directement à l'objet (du genre : objet.musée.nom, musée étant un objet d'une autre classe).
 
C'est une sorte de macro en gros que je voudrais, du genre : objet.afficher(musée.nom) qui donne system.out.println(objet.musée.nom);
 
Est ce possible en Java ? Si oui, comment ? J'ai beaucoup entendu parler de généricité, mais seulement à la création d'un objet, là c'est à l'appel d'une fonction que je voudrais cette généricité...
 
Help ! Et merci d'avance :hello:

Reply

Marsh Posté le 26-10-2004 à 15:28:13   

Reply

Marsh Posté le 26-10-2004 à 15:30:26    

rien compris, et à mon avis chuis pas le seul [:mlc]


---------------
Hey toi, tu veux acheter des minifigurines Lego, non ?
Reply

Marsh Posté le 26-10-2004 à 15:59:44    

Euh pas tout compris non plus...

Code :
  1. public Class CObjet
  2. {
  3. int ID;
  4. str name;
  5. str propriétaire;
  6. ...
  7.   void afficherID()
  8.   {
  9.   system.out.println(ID);
  10.   }
  11. }

Reply

Marsh Posté le 26-10-2004 à 17:52:33    

Je crois qu'il veut l'équivalent des "pointers to members" du C++.  
 
Sauf qu'en Java, ça se fait avec de la reflection, ou en passant le membre, tout simplement...
 
Genre, en mixant C++ et Java:
 

Code :
  1. class Machine
  2. {
  3.   string ID;
  4.   string name;
  5.   void afficher(string Machine::*truc) {
  6.     system.out.println(this->*truc);
  7. };
  8. Machine machine = (Machine) new Machine;
  9. machine.afficher(&Machine::name);


 

Reply

Marsh Posté le 26-10-2004 à 20:14:17    

lol voilà c'est bien ça, effectivement en cherchant cet aprem j'ai trouvé la reflection, mais ça ne résoud pas totalement mon problème car justement si dans CObjet j'ai une donnée membre musee du type CMusee et que je veux faire
 
objet.musee.nom
 
je peux pas le faire avec la reflection. Par contre le mix c++ / java serait exactement ce dont j'ai besoin... a condition qu'il existe en uniquement java ;) je vais chercher ça, merci... :hello:  
 
pour réexpliquer mon problème, ce que je veux c'est simplement pouvoir appeler ma fonction afficher comme ça :
 
objet.afficher(nom); et que ça m'affiche le nom de l'objet, pareil avec name et propriétaire, en écrivant qu'une seule fois la fonction.
 
Je sais pas si c'est plus clair mais je vois pas comment l'être :sweat:

Reply

Marsh Posté le 26-10-2004 à 21:20:13    

Luigi a écrit :

objet.afficher(nom); et que ça m'affiche le nom de l'objet, pareil avec name et propriétaire, en écrivant qu'une seule fois la fonction.
 
Je sais pas si c'est plus clair mais je vois pas comment l'être :sweat:


Bah surtout, ça sert pas à grand chose en pratique, don j'ai du mal à voir ton besoin. Tu peux pas détailler un peu l'usage que tu comptes en faire ?  
 
En particulier, qu'est-ce qui t'empêche de faire:

  • objet.afficher(objet.nom); ou bien
  • objet.afficher(CONST_NOM), sachant que objet saura que la constante CONST_NOM demande d'afficher son nom; ou bien
  • objet.afficherNom(), ce qui est la façon canonique de faire en Java...


 

Reply

Marsh Posté le 26-10-2004 à 21:38:54    

Ben au contraire en pratique j'en ai super souvent eu besoin sans jamais savoir le faire... Ca permet de faire un truc modulable, pas avoir à coder une fonction dix fois avec seulement un différence de l'une à l'autre. C'est l'intêret général des paramètres, mais poussé au max en fait.
 
En l'occurence, ce que je veux faire c'est une recherche multi critère sur une liste d'objets. En gros ça va donner ça (ça ressemble + a du C pasque j'ai + l'habitude) :
 
public Class CListe
 
...
 
CListe rechercher(CRITERE, valeur)
{
for(i=0; i<nb_objet; i++)
{
if(this.objet[i].CRITERE == valeur)
*ajouter à la liste des objets correspondants à la recherche*
}
}
 
L'idéal serait une sorte de macro qui carrément à l'appel me recopie mon champ CRITERE. Le but c'est que j'ai pas besoin de faire la même chose (la boucle à la con) pour chaque critère, c'est la même fonction pour tout, seuls les paramètres changent.
 
J'ai trouvé une solution pour ce problème qui est de faire un f = getDeclaredField("CRITERE" ); puis system.out.println(f.get(objet));
 
Le problème c'est quand tous les champs à recherche ne sont pas dans la classe CObjet. Dans mon cas, un objet est dans un musée, donc une donnée membre de CObjet est un pointeur vers un musée, qui, lui, contient le nom du musée. Le reflect ne permet apparement pas de gérer directement ça, alors qu'avec une "macro" j'aurais simplement à faire
 
objet.afficher(musee.nom);
 
Enfin bref, l'idée c'est de faire un truc hyper factorisé et hyper générique. Je code pas depuis super longtemps et j'ai déjà souvent été confronté à ce pb...

Reply

Marsh Posté le 26-10-2004 à 21:50:22    

Ah, je comprend mieux. Mais le problème avec ça, c'est que tu casses l'encapsulation, tu crées un couplage fort, et ça, c'est péché.
 
Ma solution, ça serait plutôt d'être plus relax, et de stocker tes attributs dans une HashMap (de String à String par exemple) dans chaque objet. Tes critères deviennent alors des trucs comme: recherche("Sexe", "30cm" );  
 
Si tu veux protéger ta liste d'attributs, tu peux alors coder une Factory (un HashMap global qui te renvoie un identifiant unique pour une chaîne donnée), et garantir qu'une chaîne existe bel et bien dans les objets de ton domaine.
 
Pour le reste, je suis loin d'être un spécialiste Java, donc je laisserai les autres te renseigner sur la Reflection.
 
PS. pense à utilise les balises code pour entourer ton code.

Reply

Marsh Posté le 26-10-2004 à 22:49:53    

j'ai pas tout compris, mais j'utilise ça pour faire de la recherche :
http://opensvn.csie.org/jcoincoin/ [...] Utils.java
 
y'a une interface Predicat (un truc qui peut être vrai ou faux) et la méthode de recherche évalue le prédicat sur les membre de la collection.
 
dans le prédicat, tu peux mettre ce que tu veux comme code.
per exemple, dans getChild(String, Node), j'ai un prédicat qui dit si le nom du node est le nom passé en paramètre de la fonction.
 
J'spère que c'est bien ta question.


---------------
trainoo.com, c'est fini
Reply

Marsh Posté le 26-10-2004 à 22:51:48    

euh moi je crois qu'il n'a pas de vraie question et qu'il aurait fallu commencer par l'orienter sur un bete toString() et ensuite possiblement sur un pattern genre visiteur


---------------
Hey toi, tu veux acheter des minifigurines Lego, non ?
Reply

Marsh Posté le 26-10-2004 à 22:51:48   

Reply

Marsh Posté le 26-10-2004 à 23:08:57    

the real moins moins a écrit :

euh moi je crois qu'il n'a pas de vraie question et qu'il aurait fallu commencer par l'orienter sur un bete toString() et ensuite possiblement sur un pattern genre visiteur


 
Ben la question c'est betement comment passer de
 
afficherID();
afficherNom();
afficherXXX();
 
à
 
afficher(champ);
 
En prenant pour hypothèse que tous les champs n'ont pas le même type et sans passer par un bête toString();
 
La réponse à cette question c'est getDeclaredFieldt(); mais ça ne permet pas que "champ" soit une donnée membre d'une autre classe (dans mon exemple : objet.musee->nom )
 
La meilleure solution il me semble est la solution mixée avec C++ qu'a donné lam's mais reste à savoir si le java le permet aussi !
 
En tout cas merci pour vos réponses, je vais regarder notament les deux dernières, faut que je fasse un peu de recherche parce que là ça ne m'a pas paru évident, mais je devrais pouvoir m'en sortir !
 
Thx ! :hello:

Reply

Marsh Posté le 26-10-2004 à 23:24:44    

ouais ben, toString() quoi
tu fais pas une methode printField, mais tu fais print(field.toString()) ou bien print(field.maSuperMethodeQuiRenvoieLeTrucFormattéCommeJeVeuxMaisFaudraitQueJApprenneCeQuEstUneInterface())


Message édité par the real moins moins le 26-10-2004 à 23:24:55

---------------
Hey toi, tu veux acheter des minifigurines Lego, non ?
Reply

Marsh Posté le 26-10-2004 à 23:44:10    

La question n'est pas que ça soit un string ou quelque formatage que ce soit, je veux pa faire un affichage, c'était un exemple pour illustrer le fait de faire rentrer une donnée membre dans les paramètres. Que dans le cas de l'affichage un toString suffise, c'est évident, mais la question c'est "faire passer une donnée membre en paramètre".
 
Dans le genre, si j'avais une liste d'objets et que je voulais une fonction qui me mette un attribut à 0 pour tous ces objets, et que je donne cet attribut en paramètre. Ce qui donnerait liste.RAZ(champ); au lieu de faire liste.RAZ_ID();, liste.RAZ_Nom();, etc.
 
Encore une fois cet exemple a peut être une autre solution (je suis un peu trop crevé pour le voir comme ça et j'ai bien évidement des connaissances limitées en java), mais reste la question générale de faire rentrer une donnée membre en paramètre. A laquelle j'ai quelques début de réponses et je vais essayer de les approfondir, mais je crois pas que toString() m'aide trop pour ça :)

Reply

Marsh Posté le 26-10-2004 à 23:47:29    

Luigi > si tu veux faire des trucs comme ça, va voir les javabeans.
 
Mais j'arrive pas à identifier ton besoin, on peut savoir ce que tu compte faire exactement ?
 
parce que si c'est pour accéder à tes membres comme ça, utilise une hashmap.


---------------
trainoo.com, c'est fini
Reply

Marsh Posté le 27-10-2004 à 00:17:59    

ptet laisser murir un peu en lisant en background un bouquin comme la bible


---------------
Hey toi, tu veux acheter des minifigurines Lego, non ?
Reply

Marsh Posté le 27-10-2004 à 07:50:30    

the real moins moins a écrit :

ptet laisser murir un peu en lisant en background un bouquin comme la bible


 
Je pense pas que la solution soit dans le GoF. C'est un problème d'idiomes, pas de patterns.  
 
Eventuellement, comme tu l'as suggéré, utiliser des interfaces qui regroupent les "attributs" communs, serait une solution. Mais le Visiteur par exemple ne résoud pas grand chose au problème en cours.
 
Sinon, un DOM classique comme l'a suggéré notre ami à bretelles, ça reste une bonne solution, et c'est un peu ce que je lui propose avec mes HashMaps... Après tout, en C++ les pointer to members sont généralement utilisés en combinaison avec des collections, pour simuler un peu d'introspection...
 

Reply

Marsh Posté le 27-10-2004 à 08:13:46    

moué, moi je veux voir le besoin réel et accrocher dessus, parce que les trucs pas typés avac aucune garanties, je fais ça que dans un cas précis : quand je connais pas à l'avance les membres.
 
ça arrive quand on fait un truc générique auquel on prévoit des extensions. la classe document de javax.swing.text fait ça, tu mets ce que tu veux dedans, mais c'est à toi de fournir l'affichage et layout (par l'editorkit qui fourni les vues).


---------------
trainoo.com, c'est fini
Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed