IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

avec Java Discussion :

Héritage : accès à une variable "fille"


Sujet :

avec Java

  1. #1
    Membre régulier Avatar de Fahelis
    Homme Profil pro
    Développeur Web
    Inscrit en
    Janvier 2014
    Messages
    77
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loiret (Centre)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : Administration - Collectivité locale

    Informations forums :
    Inscription : Janvier 2014
    Messages : 77
    Points : 87
    Points
    87
    Par défaut Héritage : accès à une variable "fille"
    Bonjour,
    Mon problème est le suivant.
    Je possède une classe Personnage et plusieurs classes dérivés de celle-ci (Guerrier, Archer, Mage).

    Dans mon programme j'instancie l'une des trois classes fille (en fonction du choix du joueur) et je stocke l'instance dans un objet de type Personnage (puisque je ne sais pas à l'avance lequel sera utilisé.)
    Mon code se résume en gros à ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    Personnage perso;
    if (event.getSource() == boutonGuerrier){
          perso = new Guerrier();
    }
    else if (event.getSource() == boutonArcher){
          perso = new Archer();
    }
    else if (event.getSource() == boutonMage){
          perso = new Mage();
    }
    Tout ceci fonctionne très bien pour tout ce que j'ai à faire, mais un seul petit truc me manque.
    J'ai dans Archer une variable de plus (une arme à distance). Comme ni le guerrier ni le mage ne peuvent en avoir, je l'avais déclaré dans Archer.
    Mais du coup je ne peux pas y accéder depuis "perso".

    Existe t-il un moyen de contourner ce problème ou dois-je déclarer mon arme à distance dans personnage, même si seul mon archer l'utilisera ?

  2. #2
    Membre habitué
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Août 2007
    Messages
    77
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Royaume-Uni

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Août 2007
    Messages : 77
    Points : 142
    Points
    142
    Par défaut
    Cela dépend un peu des méthodes et des besoins des classes en question et surtout de l'interface, mais généralement il vaut mieux trouver un moyen générique depuis l’interface.
    Pourquoi ne pas créer une interface arme, ainsi que plusieurs armes ayant chacune leurs propres caractéristiques? Chaque constructeurs de personnages sera en charge de créer sa propre instance d'arme.

  3. #3
    Modérateur

    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    12 565
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 12 565
    Points : 21 630
    Points
    21 630
    Par défaut
    On peut pas connaître la réponse parfaite à ce problème, je saurais quoi faire si c'était moi qui étais en train de faire ce programme, mais ce n'est pas moi, c'est toi.

    La question que tu dois te poser, est "pourquoi et quand je veux accéder à l'arme à distance."

    - La solution où tout le monde a la variable, n'est pas très Orientée Objet au sens Java. Mais elle est simple et pragmatique. Et si tu fais ça tes classes ne servent pas à grand-chose, il faudrait juste un enum ClasseDePersonnage qui a les valeurs GUERRIER, ARCHER, MAGE et dans ta classe Personnage tu mets juste une variable de type ClasseDePersonnage. Normalement c'est plutôt comme ça qu'on fait quand on débute... Et souvent, même quand on débute pas.

    - La solution Orientée Objet, seul l'archer a une variable arme à distance, exploite le polymorphisme. Par exemple si tu as besoin d'afficher les armes dispos d'un personnage, tu fais dans ta classe Personnage :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    protected void afficherLesArmes(InterfaceDuJeu idj) {
      idj.afficherUneArme(arme);
    }
    et dans ta classe Archer tu la redéfinis :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    @Override
    protected void afficherLesArmes(InterfaceDuJeu idj) {
      idj.afficherDeuxArmes(arme, armeADistance);
    }
    Et même raisonnement pour tous les cas où tu as besoin d'accéder à l'arme à distance s'il y en a une : faire une méthode dans Personnage et la redéfinir dans Archer, et appeler cette méthode pour qu'elle fasse ce qui doit être fait avec ou sans arme à distance.

  4. #4
    Membre régulier Avatar de Fahelis
    Homme Profil pro
    Développeur Web
    Inscrit en
    Janvier 2014
    Messages
    77
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loiret (Centre)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : Administration - Collectivité locale

    Informations forums :
    Inscription : Janvier 2014
    Messages : 77
    Points : 87
    Points
    87
    Par défaut
    Citation Envoyé par Lucio_ Voir le message
    Cela dépend un peu des méthodes et des besoins des classes en question et surtout de l'interface, mais généralement il vaut mieux trouver un moyen générique depuis l’interface.
    Pourquoi ne pas créer une interface arme, ainsi que plusieurs armes ayant chacune leurs propres caractéristiques? Chaque constructeurs de personnages sera en charge de créer sa propre instance d'arme.
    J'ai pris ici l'exemple de l'arme à distance, mais j'ai d'autres paramètres qui sont propres aux sous classes. Du coup il faudrait que je fasse une interface pour chaque ? (Je n'ai encore jamais utilisé d'interface jusque là, donc je suis pas trop au point sur le sujet).



    Citation Envoyé par thelvin Voir le message
    On peut pas connaître la réponse parfaite à ce problème, je saurais quoi faire si c'était moi qui étais en train de faire ce programme, mais ce n'est pas moi, c'est toi.

    La question que tu dois te poser, est "pourquoi et quand je veux accéder à l'arme à distance."

    - La solution Orientée Objet, seul l'archer a une variable arme à distance, exploite le polymorphisme. Par exemple si tu as besoin d'afficher les armes dispos d'un personnage, tu fais dans ta classe Personnage :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    protected void afficherLesArmes(InterfaceDuJeu idj) {
      idj.afficherUneArme(arme);
    }
    et dans ta classe Archer tu la redéfinis :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    @Override
    protected void afficherLesArmes(InterfaceDuJeu idj) {
      idj.afficherDeuxArmes(arme, armeADistance);
    }
    Et même raisonnement pour tous les cas où tu as besoin d'accéder à l'arme à distance s'il y en a une : faire une méthode dans Personnage et la redéfinir dans Archer, et appeler cette méthode pour qu'elle fasse ce qui doit être fait avec ou sans arme à distance.
    Là ça fonctionne car la methode afficherLesArmes est utiles à tous. Mais qu'en est-il pour quelque chose de vraiment spécifique à une seule classe fille.
    Exemple : J'ai aussi mes classes ennemis qui dérivent de Personnage (Gobelin, Squelette et Sorcier), le sorcier est le boss final et il possède une grosse attaque qui nécessite qu'il se concentre pendant un tour avant de la lancer.
    J'ai donc tout naturellement créer une variable booléenne "concentre" dans ma classe Sorcier, qui doit passer à true quand il lance son sort de concentration.
    Mais il est le seul concerné par cette variable. Du coup si je met ma méthode "concentration" (qui passe la variable à true) dans Personnage, c'est pas super logique car elle ne sert qu'à lui. Mais si je la met dans Sorcier (ce que j'avais fait au départ), ben du coup je ne peux pas y accéder depuis ma variable "perso".

  5. #5
    Expert éminent sénior
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 482
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 482
    Points : 48 804
    Points
    48 804
    Par défaut
    Forcément, toutes tes classes ont des comportement différents, ce qui est liée à l'usage objet et ce qui est une bonne chose. Là où te pêche, selon moi, c'est que tu essaie d'utiliser cette information à l'extérieur de la classe. Le moteur s'en fous que ton personnage se concentre, ce n'est pas à lui à gérer les spécificité de la concentration (oui ce n'est pas évident à faire en pratique comme gestion). Ce qui lui importe, c'est que le personnage a une action "concentre" et qu'elle prend un tour. Tout comme l'archer a surement une action "tir à l'arc" et qu'elle prend 0.5 tour, et donc il lui importe de savoir que l'utilisateur, peux choisir de préparer plusieurs actions (se concenter (1), lancer un sort (1) ou "tirer vaguement (0.3), tirer vaguement (0.3), tirer vaguement (0.3)" pour avoir trois tirs sur le même tour). Là t'as quelque chose de générique: getListeActionsPossible(), getListeActionsEnAttente(), setFutureActions()

  6. #6
    Membre régulier Avatar de Fahelis
    Homme Profil pro
    Développeur Web
    Inscrit en
    Janvier 2014
    Messages
    77
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loiret (Centre)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : Administration - Collectivité locale

    Informations forums :
    Inscription : Janvier 2014
    Messages : 77
    Points : 87
    Points
    87
    Par défaut
    Citation Envoyé par tchize_ Voir le message
    Forcément, toutes tes classes ont des comportement différents, ce qui est liée à l'usage objet et ce qui est une bonne chose. Là où te pêche, selon moi, c'est que tu essaie d'utiliser cette information à l'extérieur de la classe. Le moteur s'en fous que ton personnage se concentre, ce n'est pas à lui à gérer les spécificité de la concentration (oui ce n'est pas évident à faire en pratique comme gestion). Ce qui lui importe, c'est que le personnage a une action "concentre" et qu'elle prend un tour. Tout comme l'archer a surement une action "tir à l'arc" et qu'elle prend 0.5 tour, et donc il lui importe de savoir que l'utilisateur, peux choisir de préparer plusieurs actions (se concenter (1), lancer un sort (1) ou "tirer vaguement (0.3), tirer vaguement (0.3), tirer vaguement (0.3)" pour avoir trois tirs sur le même tour). Là t'as quelque chose de générique: getListeActionsPossible(), getListeActionsEnAttente(), setFutureActions()
    La pour le coup ce n'est pas la question du choix des actions (mais j'ai peut-être mal compris ce que tu essaye de me dire). C'est juste l'accès à la methode concentration.
    Elle n'a pas lui d'exister dans "Personnage" puisque seul le Sorcier l'utilise. Elle est donc dans la classe "Sorcier".
    Mais quand je suis dans ma classe "Combat" (qui me sert à gérer le combat, logique tu me diras), j'ai mon joueur "perso" de type "Personnage" (puisqu'il peut être soit Guerrier, soit Archer, soit Mage) et son ennemi "ennemi" de type "Personnage" aussi car il peut être soit Gobelin, Squelette ou Sorcier (il est différent selon la pièce dans laquelle on se trouve).
    Du coup via ma variable "ennemi", je n'ai pas accès à la méthode "concentration". Je pourrais la mettre dans "Personnage", ça réglerait facilement mon problème, mais ça me parait un peu bourrin, parce que en faisant ça, me classe filles ne servent plus à grand chose (enfin si à définir les caractéristiques au moment de l'instanciation, mais c'est tout)

  7. #7
    Modérateur

    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    12 565
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 12 565
    Points : 21 630
    Points
    21 630
    Par défaut
    concentration ne devrait pas être une méthode. Ça devrait être une sous-classe de la classe ActionPossibleEnCombat. Cette classe ressemblerait à :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    abstract class ActionPossibleEnCombat<E extends Ennemi> {
      protected abstract void effectuer(E ennemi, ContexteCombat contexte);
    }
    Ce qui donc mènera à :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    Concentrer extends ActionPossibleEnCombat<Sorcier> {
      @Override
      protected void effectuer(Sorcier sorcier, ContexteCombat contexte) {
        sorcier.enConcentration = true;
        contexte.consommeTours(1);
      }
    }
    ou quelque chose de ce genre.

    Plus qu'à avoir une méthode, pour les ennemis, qui liste leurs ActionPossibleEnCombat.

    ... Je l'ai déjà dit, je le répète, c'est pas le plus simple, penser polymorphisme. Ne pas avoir une classe pour chaque et avoir à la place une classe qui a toutes les combinaisons possibles, c'est plus simple et pragmatique. Mais c'est aussi comme ça qu'on a des bugs.

  8. #8
    Expert éminent sénior
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 482
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 482
    Points : 48 804
    Points
    48 804
    Par défaut
    Ce que j'essaie de te dire, c'est que tu prends vraisemblablement le problème à l'envers. Pourquoi tu as besoin de savoir que le personnage se concentre? Parce que ça à une influence sur le combat. Mais des tas de choses peuvent avoir une influence sur le combat, et quelque part, c'est cette influence qui est ton élément générique, ton polymorphisme. Chaque personnage aura sa propre manière d'influer sur un combat, en fonction de ses caractéristiques. Le sorcier ce sera à cause de la concentration, le goblin parce qu'il peut paniquer et prendre la fuite, le barbare parce qu'il peut pousser un cri de guerre, etc...

  9. #9
    Membre régulier Avatar de Fahelis
    Homme Profil pro
    Développeur Web
    Inscrit en
    Janvier 2014
    Messages
    77
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loiret (Centre)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : Administration - Collectivité locale

    Informations forums :
    Inscription : Janvier 2014
    Messages : 77
    Points : 87
    Points
    87
    Par défaut
    Citation Envoyé par thelvin Voir le message
    concentration ne devrait pas être une méthode. Ça devrait être une sous-classe de la classe ActionPossibleEnCombat. Cette classe ressemblerait à :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    abstract class ActionPossibleEnCombat<E extends Ennemi> {
      protected abstract void effectuer(E ennemi, ContexteCombat contexte);
    }
    Ce qui donc mènera à :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    Concentrer extends ActionPossibleEnCombat<Sorcier> {
      @Override
      protected void effectuer(Sorcier sorcier, ContexteCombat contexte) {
        sorcier.enConcentration = true;
        contexte.consommeTours(1);
      }
    }
    ou quelque chose de ce genre.

    Plus qu'à avoir une méthode, pour les ennemis, qui liste leurs ActionPossibleEnCombat.

    ... Je l'ai déjà dit, je le répète, c'est pas le plus simple, penser polymorphisme. Ne pas avoir une classe pour chaque et avoir à la place une classe qui a toutes les combinaisons possibles, c'est plus simple et pragmatique. Mais c'est aussi comme ça qu'on a des bugs.
    Je n'avais pas envisagé de faire une classe pour mes actions. Actuellement mes actions sont des méthodes de la classe Personnage (attaque, esquive, lancer un sort...). Du coup ça m'obligerait à tout restructurer, ça risque de me prendre pas mal de temps.

    Citation Envoyé par tchize_ Voir le message
    Ce que j'essaie de te dire, c'est que tu prends vraisemblablement le problème à l'envers. Pourquoi tu as besoin de savoir que le personnage se concentre? Parce que ça à une influence sur le combat. Mais des tas de choses peuvent avoir une influence sur le combat, et quelque part, c'est cette influence qui est ton élément générique, ton polymorphisme. Chaque personnage aura sa propre manière d'influer sur un combat, en fonction de ses caractéristiques. Le sorcier ce sera à cause de la concentration, le goblin parce qu'il peut paniquer et prendre la fuite, le barbare parce qu'il peut pousser un cri de guerre, etc...
    En fait ce que tu me suggère (si je comprend bien) c'est une méthode du genre "action spéciale" à mettre dans "Personnage" et de la redéfinir ensuite dans chaque sous classe avec les particularités nécessaires (par exemple "concentre = true" pour mon sorcier) dans chaque classe fille.

  10. #10
    Expert éminent sénior
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 482
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 482
    Points : 48 804
    Points
    48 804
    Par défaut
    Ca pourrait être une solution oui. Il y en a d'autre bien sûr possible, tout dépendra de comment évolue ton code. Tu n'a pas pris l'exemple le plus facile pour débuter en poo avec un moteur de jeu de rôle, parce que là dedans, typiquement, ça part dans tous les sens

  11. #11
    Membre régulier Avatar de Fahelis
    Homme Profil pro
    Développeur Web
    Inscrit en
    Janvier 2014
    Messages
    77
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loiret (Centre)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : Administration - Collectivité locale

    Informations forums :
    Inscription : Janvier 2014
    Messages : 77
    Points : 87
    Points
    87
    Par défaut
    Citation Envoyé par tchize_ Voir le message
    Ca pourrait être une solution oui. Il y en a d'autre bien sûr possible, tout dépendra de comment évolue ton code. Tu n'a pas pris l'exemple le plus facile pour débuter en poo avec un moteur de jeu de rôle, parce que là dedans, typiquement, ça part dans tous les sens
    Oui c'est ce que je me suis dis aussi au fur et à mesure que j'avançais lol
    Enfin bon, du coup je vais en effet faire comme ça, ça devrait suffire.

    Merci à tous pour vos réponses

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 5
    Dernier message: 18/09/2008, 17h20
  2. Acces à une variable-tableau de PHP
    Par Erwan21 dans le forum Général JavaScript
    Réponses: 5
    Dernier message: 09/02/2005, 13h55
  3. [héritage] héritage d'une variable static
    Par yaya44 dans le forum Langage
    Réponses: 14
    Dernier message: 29/09/2004, 13h36

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo