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 et retourner objet type classe fille


Sujet :

avec Java

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé Avatar de vertebre
    Homme Profil pro
    Étudiant
    Inscrit en
    Janvier 2015
    Messages
    184
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Janvier 2015
    Messages : 184
    Par défaut Héritage et retourner objet type classe fille
    Bonjour,

    J'ai défini une classe AObjet, une de ses class filles est Trophe.
    Je tente de retourner un trophe qui est contenu dans un tableau d'AObjet.
    En instanciant ou sans instancier un objet il ne m'est pas possible de retourner le bon type (à savoir un trophee)

    en gros ce que je voudrais faire, c'est
    // parcourir tabRecompense[] tant qu'il ne trouve pas de Trophe
    // Me renvoyer le trophée dès qu'il est trouvé

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     public Trophe giveTropheeInTab(AObjet[] tabRecompense, int indice){
            int indice2 = -1;
            Trophe trophe = new Trophe();
            Class classTrophe = trophe.getClass();
            indice = giveIndice_FirstVal_InTab(tabRecompense);
            for (int i=0;i<tabRecompense.length;i++) {
                if (tabRecompense[indice].getClass() == classTrophe) {
                        indice2 = i;
                        break;
                }
            }
            return tabRecompense[indice2];
        }
    Au passage j'en profite pour vous demander pourquoi lorsque je met mon return tabRecompense[indice2] dans le if, il considère que la méthode ne renvoie rien ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     public Trophe giveTropheeInTab(AObjet[] tabRecompense, int indice){
            Trophe trophe = new Trophe();
            Class classTrophe = trophe.getClass();
            indice = giveIndice_FirstVal_InTab(tabRecompense);
            for (int i=0;i<tabRecompense.length;i++) {
                if (tabRecompense[indice].getClass() == classTrophe) {
                        return tabRecompense[indice2];
                        break;
                }
            }
     
        }
    merci de votre aide,

  2. #2
    Modérateur
    Avatar de joel.drigo
    Homme Profil pro
    Ingénieur R&D - Développeur Java
    Inscrit en
    Septembre 2009
    Messages
    12 430
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 55
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur R&D - Développeur Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2009
    Messages : 12 430
    Billets dans le blog
    2
    Par défaut
    Salut,

    Premièrement, au lieu de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    Trophe trophe = new Trophe();
            Class classTrophe = trophe.getClass();
            indice = giveIndice_FirstVal_InTab(tabRecompense);
            for (int i=0;i<tabRecompense.length;i++) {
                if (tabRecompense[indice].getClass() == classTrophe) {
    /*...*/
    Fais

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
            indice = giveIndice_FirstVal_InTab(tabRecompense);
            for (int i=0;i<tabRecompense.length;i++) {
                if (tabRecompense[indice] instanceof Trophe ) {
    A noter qu'ici, même si tabRecompense[indice] est d'une classe qui étend Trophe, la condition sera vraie.

    Si tu as besoin d'un objet de la classe Trophe, mais pas de ses sous classes, au lieu d'instancier un objet de classe Trophe (inutilement, et, dans le cas général, pas forcément faisable selon les constructeurs disponibles), tu peux écrire Trophee.class directement pour obtenir l'instance (singleton) de Class. Par exemple :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    if (tabRecompense[indice].getClass() == Trophe.class )
    Citation Envoyé par vertebre Voir le message
    Au passage j'en profite pour vous demander pourquoi lorsque je met mon return tabRecompense[indice2] dans le if, il considère que la méthode ne renvoie rien ?
    Je ne pense pas que le compilateur considère ne rien renvoyer, mais plutôt t'indique-t-il que tu cherches à renvoyer un objet de type inadéquat, parce que tu retournes du AObjet (le type du tableau), alors que la méthode est censée retourner du Trophe. Il est donc nécessaire de caster dans le bon type : return (Trophe)tabRecompense[indice2];.

    Par ailleurs, l'objet de type Trophe pouvant ne pas être trouvé, dans ce cas indice2 restera à -1, et donc tabRecompose[indice2] sera inexistant (tu obtiendras une ArrayOutOfBoundException : dépassement de bornes). Il te faut donc tester indice2 pour ne pas avoir cette exception, et retourner autre chose, par exemple null, lorsqu'aucun Trophe n'est trouvé.

    Enfin, pourquoi indice est-il un paramètre de la méthode ? D'autant plus que tu n'utilises jamais la valeur passée en argument !

    Pour la seconde version de la méthode, tu ne peux mettre de code après un return, dans la même séquence que ce return (ça ne compilera pas), parce que return marque la fin de la séquence justement. L'appel de break, inutile par ailleurs (le return fait déjà un break en quelque sorte), doit être supprimé.
    L'expression "ça marche pas" ne veut rien dire. Indiquez l'erreur, et/ou les comportements attendus et obtenus, et donnez un Exemple Complet Minimal qui permet de reproduire le problème.
    La plupart des réponses à vos questions sont déjà dans les FAQs ou les Tutoriels, ou peut-être dans une autre discussion : utilisez la recherche interne.
    Des questions sur Java : consultez le Forum Java. Des questions sur l'EDI Eclipse ou la plateforme Eclipse RCP : consultez le Forum Eclipse.
    Une question correctement posée et rédigée et vous aurez plus de chances de réponses adaptées et rapides.
    N'oubliez pas de mettre vos extraits de code entre balises CODE (Voir Mode d'emploi de l'éditeur de messages).
    Nouveau sur le forum ? Consultez Les Règles du Club.

  3. #3
    Membre confirmé Avatar de vertebre
    Homme Profil pro
    Étudiant
    Inscrit en
    Janvier 2015
    Messages
    184
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Janvier 2015
    Messages : 184
    Par défaut
    Merci pour tes réponses

    voilà j'ai refait la méthode avec les éléments que tu m'as expliqué:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    // Méthode retournant le trophee présent dans le tableau de récompense
        public Trophe giveTropheeInTab(AObjet[] tabRecompense){
            int indice = -1;
            for (int i=0;i<tabRecompense.length;i++) {
                if (tabRecompense[indice] instanceof Trophe) {
                    indice = i;
                    break;
                }
            }
    if (indice!=-1)
            return (Trophe)tabRecompense[indice];
        }
    Cela fonctionne très bien; en effet j'avais oublié le cast que je n'ai jamais trop utilisé.
    Je pensais cela réservé au int et double par exemple; mais cela voudra dire que le type int hérite de double ? ou cela n'a rien a voir ?


    pourquoi lorsque je met mon return tabRecompense[indice2] dans le if, il considère que la méthode ne renvoie rien ?
    Il m'indique précisément 'missing return statement' pour ~état de retour oublié
    J'ai toujours cette erreur en castant.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    public Trophe giveTropheeInTab(AObjet[] tabRecompense) {
            for (int i=0;i<tabRecompense.length;i++) {
                if (tabRecompense[indice] instanceof Trophe) {
                    return (Trophe)tabRecompense[i];
                }
            }
        }


    Concernant le test de mon indice j'obtiens encore un 'missing return statement' lorsque je fais çà
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
     
    public Trophe giveTropheeInTab(AObjet[] tabRecompense){
            int indice = -1;
            for (int i=0;i<tabRecompense.length;i++) {
                if (tabRecompense[indice] instanceof Trophe) {
                    indice = i;
                }
            }
            if(indice!=-1){
            return (Trophe)tabRecompense[indice];
              }
            else {
                System.out.println("Erreur le trophée n'existe pas");
            }
        }
    Pour gérer ce problème d'indice -1, case qui n'existe pas, serait ce mieux d'utiliser un try {} catch {} ?
    si oui que faire dans ce cas à part afficher une erreur comme mon if ?
    Sachant que ce tabRecompense(coté client) recevra le trophée en question du serveur, il faudra attendre le résultat de la requête si elle n'est pas instantanée ?
    J'avais pensé à vérifier par intervalle régulier ? mais est ce la bonne idée ?


    Enfin, pourquoi indice est-il un paramètre de la méthode ? D'autant plus que tu n'utilises jamais la valeur passée en argument !
    Je voulais utiliser mon autre fonction qui me retourne directement l'indice du 1er trophée trouvé dans le tableau tabRecompense, mais qui ne doit pas être correct non plus

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    // Méthode retournant l'indice du 1ere objet trophee trouvé dans le tableau
        public int giveIndice_FirstVal_InTab(AObjet[] tabRecompense){
            int indice = 0;
     
            for (int i=0;i<tabRecompense.length;i++){
                if (tabRecompense[i].getIdObjet().getTypeObjet() == "Trophe")
                    indice = i;
                break;
            }
            return indice;
        }
    En fait comme je ne comprenais pas qu'il fallait caster, je vérifiais mes types d'AObjet gràce à leur attribut idObjet, mieux vaut utiliser le cast ou idObjet ?

  4. #4
    Modérateur
    Avatar de joel.drigo
    Homme Profil pro
    Ingénieur R&D - Développeur Java
    Inscrit en
    Septembre 2009
    Messages
    12 430
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 55
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur R&D - Développeur Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2009
    Messages : 12 430
    Billets dans le blog
    2
    Par défaut
    Citation Envoyé par vertebre Voir le message
    Merci pour tes réponses

    voilà j'ai refait la méthode avec les éléments que tu m'as expliqué:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    // Méthode retournant le trophee présent dans le tableau de récompense
        public Trophe giveTropheeInTab(AObjet[] tabRecompense){
            int indice = -1;
            for (int i=0;i<tabRecompense.length;i++) {
                if (tabRecompense[indice] instanceof Trophe) {
                    indice = i;
                    break;
                }
            }
    if (indice!=-1)
            return (Trophe)tabRecompense[indice];
        }
    Cela fonctionne très bien; en effet j'avais oublié le cast que je n'ai jamais trop utilisé.
    Je pensais cela réservé au int et double par exemple; mais cela voudra dire que le type int hérite de double ? ou cela n'a rien a voir ?



    Il m'indique précisément 'missing return statement' pour ~état de retour oublié
    J'ai toujours cette erreur en castant.
    Oui, parce que maintenant, il y a un return si indice!=-1, mais aucun si indice vaut -1 !!!


    Exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     public Trophe giveTropheeInTab(AObjet[] tabRecompense){
            int indice = -1;
            for (int i=0;i<tabRecompense.length;i++) {
                if (tabRecompense[indice] instanceof Trophe) {
                    indice = i;
                    break;
                }
            }
    if (indice!=-1)
            return (Trophe)tabRecompense[indice];
        }
    return null; // si indice==-1
    Attention, maintenant ta méthode peut retourner null, donc il faudra faire attention lorsque tu utilises le résultat de l'appel de cette méthode, sinon risque de NullPointerException. C'est peut-être prématuré pour ton niveau de Java, mais tu verras plus tard qu'on a introduit dans Java en version 8 la classe Optional, qui te permet de gérer ce genre de cas, sans risque de NullPointerException (mais qui ne t’exonérera pas de test)

    Citation Envoyé par vertebre Voir le message

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    public Trophe giveTropheeInTab(AObjet[] tabRecompense) {
            for (int i=0;i<tabRecompense.length;i++) {
                if (tabRecompense[indice] instanceof Trophe) {
                    return (Trophe)tabRecompense[i];
                }
            }
        }


    Concernant le test de mon indice j'obtiens encore un 'missing return statement' lorsque je fais çà
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
     
    public Trophe giveTropheeInTab(AObjet[] tabRecompense){
            int indice = -1;
            for (int i=0;i<tabRecompense.length;i++) {
                if (tabRecompense[indice] instanceof Trophe) {
                    indice = i;
                }
            }
            if(indice!=-1){
            return (Trophe)tabRecompense[indice];
              }
            else {
                System.out.println("Erreur le trophée n'existe pas");
            }
        }
    Exactement le même problème et la même solution : ta méthode doit retourner une instance de Trophe, ou null !

    Citation Envoyé par vertebre Voir le message
    Pour gérer ce problème d'indice -1, case qui n'existe pas, serait ce mieux d'utiliser un try {} catch {} ?
    si oui que faire dans ce cas à part afficher une erreur comme mon if ?
    Certainement pas : un try/catch est pour attraper une exception produit par un code appelé.
    Peut être voulais tu dire de soulever une exception (faire un throw), et de faire un try/catch dans l'appelant : c'est effectivement une solution, meilleure dans pas mal de cas que celle que je t'ai indiqué, mais qui peut rendre plus contraignante l'utilisation de ta méthode, si l'exception est dite checked (si on est obligé de faire un try/catch quand on l'appelle). Tu peux utiliser éventuellement une RuntimeException (dite unchecked, parce qu'on est pas obligé de l'attraper par un try/catch). Par exemple l'exception java.util.NoSuchElementException.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
     
    public Trophe giveTropheeInTab(AObjet[] tabRecompense){
            int indice = -1;
            for (int i=0;i<tabRecompense.length;i++) {
                if (tabRecompense[indice] instanceof Trophe) {
                    indice = i;
                }
            }
            if(indice!=-1){
            return (Trophe)tabRecompense[indice];
              }
            else {
                throw new NoSuchElementException("Erreur le trophée n'existe pas");
            }
        }
    Cette solution a un peu le défaut de son avantage : le try/catch n'est pas obligatoire, donc tant que ton programme trouve un trophee dans tous les cas d'appel, aucun problème, tout fonctionne. Mais si ce n'est pas le cas, l'exception remontera jusqu'à la racine de la stacktrace de ton thread d'exécution, et ne sera potentiellement pas visible (ça plantera, mais tu ne sauras pas pourquoi, selon la manière que tu exécutes (avec/sans console), tu logues tes exceptions, tu traites ce qu'on appelle les UncaughException, etc... des notions qui sont peut-être un peu avancéespour que tu aies à la gérer à ton niveau...)






    Citation Envoyé par vertebre Voir le message

    Sachant que ce tabRecompense(coté client) recevra le trophée en question du serveur, il faudra attendre le résultat de la requête si elle n'est pas instantanée ?
    J'avais pensé à vérifier par intervalle régulier ? mais est ce la bonne idée ?
    ça c'est une autre question, et il faudrait que j'en sache plus. Il y a plusieurs manière de le faire, et "vérifier par intervalle régulier", soit du polling n'est pas la meilleure, même si c'est parfois la seule possible.
    Mais je pense que tu es plutôt dans le contexte d'une interface graphique à mettre à jour, n'est-ce-pas : tu lances une requête à un serveur, pour connaitre le trophée, et quand la requête "répond", l'affichage doit se mettre à jour... un SwingWorker est une solution si c'est le cas. Sinon, un système évènementiel personnalisé.


    Citation Envoyé par vertebre Voir le message
    Je voulais utiliser mon autre fonction qui me retourne directement l'indice du 1er trophée trouvé dans le tableau tabRecompense, mais qui ne doit pas être correct non plus

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    // Méthode retournant l'indice du 1ere objet trophee trouvé dans le tableau
        public int giveIndice_FirstVal_InTab(AObjet[] tabRecompense){
            int indice = 0;
     
            for (int i=0;i<tabRecompense.length;i++){
                if (tabRecompense[i].getIdObjet().getTypeObjet() == "Trophe")
                    indice = i;
                break;
            }
            return indice;
        }
    En fait comme je ne comprenais pas qu'il fallait caster, je vérifiais mes types d'AObjet gràce à leur attribut idObjet, mieux vaut utiliser le cast ou idObjet ?
    La notion de typage est souvent meilleure que d'utiliser les classes en elle-même (faire des instanceof ce n'est jamais une bonne solution pour l'evolutivité de ton programme). Utiliser de préférence une enum si l'ensemble des types est fini et immuable, et si tu veux qu'ils soient extensibles, des String peuvent faire l'affaire, mais surtout ne pas les comparer avec == mais avec equals() (== teste l'identité des références d'instances, pas l'égalité des chaines).

    Autre détail de taille : initialise indice à 0, sinon tu ne pourras pas distinguer le cas où le trophée est en position 0 et celui où il n'y a aucun trophée dans le tableau !
    L'expression "ça marche pas" ne veut rien dire. Indiquez l'erreur, et/ou les comportements attendus et obtenus, et donnez un Exemple Complet Minimal qui permet de reproduire le problème.
    La plupart des réponses à vos questions sont déjà dans les FAQs ou les Tutoriels, ou peut-être dans une autre discussion : utilisez la recherche interne.
    Des questions sur Java : consultez le Forum Java. Des questions sur l'EDI Eclipse ou la plateforme Eclipse RCP : consultez le Forum Eclipse.
    Une question correctement posée et rédigée et vous aurez plus de chances de réponses adaptées et rapides.
    N'oubliez pas de mettre vos extraits de code entre balises CODE (Voir Mode d'emploi de l'éditeur de messages).
    Nouveau sur le forum ? Consultez Les Règles du Club.

  5. #5
    Membre confirmé Avatar de vertebre
    Homme Profil pro
    Étudiant
    Inscrit en
    Janvier 2015
    Messages
    184
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Janvier 2015
    Messages : 184
    Par défaut
    Oui, parce que maintenant, il y a un return si indice!=-1, mais aucun si indice vaut -1 !!!
    Ah oui mince



    ta méthode peut retourner null, donc il faudra faire attention lorsque tu utilises le résultat de l'appel de cette méthode, sinon risque de NullPointerException.
    null, je n'y avais pas pensé, mais 2 questions me viennent :

    1) Quelle est la différence réel pour mes trophées entre :
    indice = -1 --> Le trophée n'existe pas
    et
    tabRecompense[indice2] = null --> Le trophée n'existe pas non plus ?

    2) Comment traiter proprement toutes les exceptions?
    J'entend par là, si j'ai un interface avec 30 fonctions/méthodes et que j'ai une class qui implémente cet interface ... euh je vais avoir des fonct°/Méthodes à rallonge et du coup un fichier de fou ?
    Suis je obligé de faire comme çà si je veux gérer toutes les exceptions ?



    Cette solution a un peu le défaut de son avantage : le try/catch n'est pas obligatoire, donc tant que ton programme trouve un trophee dans tous les cas d'appel, aucun problème, tout fonctionne. Mais si ce n'est pas le cas, l'exception remontera jusqu'à la racine de la stacktrace de ton thread d'exécution, et ne sera potentiellement pas visible[...]
    Je ne comprend pas pourquoi elle ne serait potentiellement pas visible, vu que l'on a un message d'erreur NoSuchElementException("Erreur le trophée n'existe pas") ?
    Je le verrrais ce message non ?



    La notion de typage est souvent meilleure que d'utiliser les classes en elle-même (faire des instanceof ce n'est jamais une bonne solution pour l'evolutivité de ton programme).
    euh c'est que j'ai du mal à comprendre mais tu veux dire que c'est préférable de faire comme j'ai fait, plutôt qu'avec un instanceof (au niveau de la méthode giveIndice_FirstVal_InTab()) ?



    Utiliser de préférence une enum si l'ensemble des types est fini et immuable, et si tu veux qu'ils soient extensibles
    Dans mon application, j'ai des types(des sortes) d'AObjets, j'ai stocké ces valeurs dans une constante tableau de string et le tout dans un interface.
    D'après ce que tu me dis, ce serait mieux de mettre tous çà dans un enum ?
    Ce que je ne comprend pas vraiment c'est la phrase suivante:
    "type fini et immuable", c'est par rapport à mes types d'attribut que je vais mettre dans la classe enum, on ne rajoutera pas de nouveau type ?
    "extensibles" c'est par rapport à la quantité des données des attributs que je vais mettre dans l'enum ?
    Sorry je ne connaissais pas les enum, je viens juste de lire un article dessus pour me renseigner.


    Autre détail de taille : initialise indice à 0, sinon tu ne pourras pas distinguer le cas où le trophée est en position 0 et celui où il n'y a aucun trophée dans le tableau !
    Je pensais l'avoir intialisé à -1 pour ne pas le confondre avec le 0... pourrais tu me donner un exemple parce que je n'arrive pas à comprendre pourtant c'est très basique

    Parlez avec toi c'est très enrichissant mais je ne vois plus l'horizon dans mon application

  6. #6
    Expert éminent
    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 : 46
    Localisation : Belgique

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

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 482
    Par défaut
    Citation Envoyé par vertebre Voir le message

    1) Quelle est la différence réel pour mes trophées entre :
    indice = -1 --> Le trophée n'existe pas
    et
    tabRecompense[indice2] = null --> Le trophée n'existe pas non plus ?
    C'est à toi de définir ça En fonction de ton modèle tu peux ou pas vouloir donner une signifiaction différente.

    Citation Envoyé par vertebre Voir le message
    2) Comment traiter proprement toutes les exceptions?
    J'entend par là, si j'ai un interface avec 30 fonctions/méthodes et que j'ai une class qui implémente cet interface ... euh je vais avoir des fonct°/Méthodes à rallonge et du coup un fichier de fou ?
    Suis je obligé de faire comme çà si je veux gérer toutes les exceptions ?
    L'interface déclare les méthodes qui peuvent être lancée. Donc il te suffit de restreindre le nombre d'exception pouvant être lancée par ton code. Pour ce qui est des exception lancées par les api que tu utilise. Soit tu catch si c'est nécessaire, soit tu fait remonter. Les RuntimeException et toutes leurs fille ne doivent pas être déclarée dans l'interface. Exemple: on ne déclare par qu'un méthode peux lancer un NullPointerException, c'est une erreur de programmation en général, on la laisse tout pêter et on corrige le code.



    Citation Envoyé par vertebre Voir le message

    Je ne comprend pas pourquoi elle ne serait potentiellement pas visible, vu que l'on a un message d'erreur NoSuchElementException("Erreur le trophée n'existe pas") ?
    Je le verrrais ce message non ?
    Si tu lance une exception que rien n'attrape, elle finira en général dans la console, donc oui tu verra le message. Si c'est une erreur de programmation, c'est bien. Si c'est un comportement attendu du programme, c'est mal, il faut traiter




    Citation Envoyé par vertebre Voir le message
    euh c'est que j'ai du mal à comprendre mais tu veux dire que c'est préférable de faire comme j'ai fait, plutôt qu'avec un instanceof (au niveau de la méthode giveIndice_FirstVal_InTab()) ?
    Non, il dit qu'en général, quand c'est possible, il faut utiliser les Generic, comme ça le compilateur peut déjà vérifier que tout est possible.

  7. #7
    Modérateur
    Avatar de joel.drigo
    Homme Profil pro
    Ingénieur R&D - Développeur Java
    Inscrit en
    Septembre 2009
    Messages
    12 430
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 55
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur R&D - Développeur Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2009
    Messages : 12 430
    Billets dans le blog
    2
    Par défaut
    Citation Envoyé par vertebre Voir le message
    Ah oui mince





    null, je n'y avais pas pensé, mais 2 questions me viennent :

    1) Quelle est la différence réel pour mes trophées entre :
    indice = -1 --> Le trophée n'existe pas
    et
    tabRecompense[indice2] = null --> Le trophée n'existe pas non plus ?
    Je n'ai pas dit de mettre null dans tabRecompense[indice2] (qui ne fonctionnerait pas puisque indice vaut -1), mais de faire return null.
    indice c'est juste la variable qui te permet de retrouver l'élément de tabRecompense trouvé dans la boucle. Lorsque cette variable a une valeur qui ne correspond à aucun élément, comme il faut en retourner un, qui n'existe pas dans le tableau, on retourne quelque chose d'autre : ça peut être null, mais aussi une valeur par défaut, une valeur au hasard, peu importe.

    Par exemple, si je veux faire une méthode qui retourne la première voyelle (sans accent) trouvée dans un texte, je peux faire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    public char getPremiereVoyelle(String texte) {
       for(int i=0; i<texte.length; i++) { 
          char c=texte.charAt(i);
          if ( "aeiouy".indexOf(c)>=0 ) {
               return c; // j'ai trouvé une voyelle, je la retourne
          }
       }
      // ici, il faut que je retourne absolument quelque chose, ou que je soulève une exception, c'est obligatoire, sinon ça ne compile pas
     
    }

    Citation Envoyé par vertebre Voir le message
    2) Comment traiter proprement toutes les exceptions?
    J'entend par là, si j'ai un interface avec 30 fonctions/méthodes et que j'ai une class qui implémente cet interface ... euh je vais avoir des fonct°/Méthodes à rallonge et du coup un fichier de fou ?
    Suis je obligé de faire comme çà si je veux gérer toutes les exceptions ?
    Tu parles de quel traitement : soulever une exception lorsque les données ne sont pas correctes ? Ou attraper les exceptions soulevées par d'autres traitements dans ton propre code ?
    Sinon, ça dépend. Dans l'absolu oui, il vaut mieux traiter toutes les exceptions qui peuvent arriver, mais surtout celle que tu sais traiter. Dans le cas suivant, inutile de traiter une NullPointer Exception : ça n'arrive pas :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    public int truc(int bidule, int machin) {
     
        return bidule/machin;
     
    }
    Mais une ArithmeticException, avec le message "Divide by zero", oui, parce qu'on peut passer 0 en second argument. Maintenant, Java traitera de toute manière ce cas, donc le programme plantera de toute manière. Mais tu peux aussi t'arranger pour que ça n'arrive jamais, en appelant pas la méthode si machin vaut 0 (par exemple, si dans une IHM empêcher l'utilisateur de choisir 0 comme diviseur.

    En fait, il y a autant de manière de gérer les erreurs que de cas rencontrable : attraper les erreurs, les spécialiser, les traiter par une classe à part dédiée (ErrorHandler), les tracer dans un fichier, empêcher qu'elles se passent, ou trouver un moyen de les contourner, etc.
    Mais ce qui sûr et certain c'est qu'une méthode doit retourner un résultat si elle n'est pas void, ou soulever une exception. Si tu as 30 méthodes ou 500, il faut le faire, c'est tout. Maintenant, il faut aussi se poser la question : "est-ce que c'est normal qu'il y ait 30 mé(thodes dans ma classe ?", "ne puis-je pas factoriser mes méthodes ?".

    Par exemple :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    public class Exemple {
     
         private AObject[] array = ...
     
         public Trophe getTrophe() {
              return getPremier(array, Trophee.class);
         }
     
         public Machin getMachin() {
              return getPremier(array, Machin.class);
         }
     
         private <T> T getPremier(AObject[] array, Class<T> klass) {
     
               for(AObject object : array) {
                     if ( klass.isInstanceOf(object) ) {
                          return klass.cast(object);
                     }
               }
               throw new NoSuchElementException("Aucun élément de type "+klass);
     
         }
     
    }
    Je peux avoir 30 méthode getTruc() getBidule() etc..., j'ai tout géré dans une seule méthode, au lieu de répeter 30 fois un code très similaire.

    Citation Envoyé par vertebre Voir le message

    Je ne comprend pas pourquoi elle ne serait potentiellement pas visible, vu que l'on a un message d'erreur NoSuchElementException("Erreur le trophée n'existe pas") ?
    Je le verrrais ce message non ?
    ça dépend comment tu exécutes ton programme : si tu fais un jar exécutable et que tu doubles cliques dessus pour le lancer, tu ne la verras pas, parce qu'il n'y a pas de console. Il y a d'autres cas où même s'il y a une console, l'exception n'est pas visible (exemple, en Java 5, avec un ExecutorService, en cas d'erreur non attrapée, le thread plante et l'exception n'est pas tracée : il fallait indiquer UncaughtExceptionHandler pour en avoir une.




    Citation Envoyé par vertebre Voir le message
    euh c'est que j'ai du mal à comprendre mais tu veux dire que c'est préférable de faire comme j'ai fait plutôt qu'avec un instanceof (au niveau de la méthode giveIndice_FirstVal_InTab()) ?
    L'instanceOf est une contrainte sur une classe, ce qui est toujours un problème : ça te lie trop aux classes de tes objets, et peut te poser des problèmes par la suite, ou poser des problèmes à d'autres qui auraient besoin de construire un autre programme à partir du tiens, voire à toi même d'ailleurs. On ne peut pas toujours réécrire tout à zéro : c'est toujours un avantage de pouvoir réutiliser ce qu'on a déjà fait ou d'autres ont fait, avec un maximum de souplesse.

    Si tu fais un instanceof K, et qu'on veut appliquer le même traitement à une instance de classe L, parce que c'est le même type, on ne pourra pas sans modifier ton code, ce qui n'est pas forcément faisable facilement, et plutôt à éviter en général. Avec un type, on peut avoir les 2 instances de classe K et L qui on le même type et donc sera traitée de la même manière.
    Autre problème, si tu as une classe M avec un traitement sur instanceof M, et que tu fais une classe N qui étend M, et que tu veux pas le traitement qui s'applique sur celle de M s'applique sur celle de N, tu vas devoir aussi bidouiller.
    En plus avec un typage, que cela soit une enum ou un String, un switch sera plus clair et plus simple qu'une série if ( ... instanceof ) else if ( ...instanceof...)...
    Normalement la structure de classe doit être organisée de manière à ce que les instances, par le biais des surcharges et des redéfinitions, se comportent chacune comme elles le devraient, sans avoir à faire d'instanceof. Idem pour le typage d'ailleurs, mais avec le typage, on est plus souple pour faire un peu ce qu'on veut.


    Citation Envoyé par vertebre Voir le message
    Dans mon application, j'ai des types(des sortes) d'AObjets, j'ai stocké ces valeurs dans une constante tableau de string et le tout dans un interface.
    D'après ce que tu me dis, ce serait mieux de mettre tous çà dans un enum ?
    Ce que je ne comprend pas vraiment c'est la phrase suivante:
    "type fini et immuable", c'est par rapport à mes types d'attribut que je vais mettre dans la classe enum, on ne rajoutera pas de nouveau type ?
    Une enum est figée au cours d'une exécution : au moment, où tu la crées (tu écris le code), tu décides des valeurs qui existeront, et il n'y en aura pas d'autres.
    En matière d'ihm, on peut dire que pour saisir une information définie par une enum, on utilise une combo non éditable, voire une série de radiobuttons s'il y a peu de valeurs dans l'enum
    Mais on peut toujours ajouter des nouveaux types et ré exécuter le programme.

    Citation Envoyé par vertebre Voir le message
    "extensibles" c'est par rapport à la quantité des données des attributs que je vais mettre dans l'enum ?
    Sorry je ne connaissais pas les enum, je viens juste de lire un article dessus pour me renseigner.
    Extensible, sous-entendu par l'utilisateur du programme. En matière d'IHM, on utilisera une combo éditable, préremplie avec les valeurs décidées dans le code, mais l'utilisateur pourra choisir sa propre valeur.

    Avec une enum, on peut avoir besoin de prévoir une valeur d'enum AUTRE, ou INCONNU. L'avantage d'une enum (en plus d'être plus efficace (performance/mémoire)), c'est qu'on peut attacher du code à chaque valeur, et donc éviter de faire justement des if else/if ou des switchs.

    Par exemple, on peut faire une enum pour déplacer un truc :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    public enum Direction {
     
            NORD(0,-1),
            EST(1,0),
            SUD(0,1),
            OUEST(-1,0);
     
            private final int dx;
            private final int dy;
     
            private Direction(int dx, int dy) {
               this.dx=dx;
               this.dy=dy;
            }
     
            public Point move(Point p) {
                 return new Point(p.x+dx, p.y+dy);
            }
     
    }
    Aucun, if, switch, ou autre... et si on veut faire un déplacement NORD_OUEST, on l'ajoute à la liste de valeur NORD_OUEST(-1,-1).


    Citation Envoyé par vertebre Voir le message
    Je pensais l'avoir intialisé à -1 pour ne pas le confondre avec le 0... pourrais tu me donner un exemple parce que je n'arrive pas à comprendre pourtant c'est très basique
    Oups, coquille de ma part, je voulais dire " initialise indice à -1, sinon tu ne pourras pas distinguer le cas où le trophée est en position 0 et celui où il n'y a aucun trophée dans le tableau ! "
    Parce que dans ce code, tu l'initialises à 0 :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    public int giveIndice_FirstVal_InTab(AObjet[] tabRecompense){
            int indice = 0; // <= là, il faut -1
     
            for (int i=0;i<tabRecompense.length;i++){
                if (tabRecompense[i].getIdObjet().getTypeObjet() == "Trophe")
                    indice = i;
                break;
            }
            return indice;
        }
    L'expression "ça marche pas" ne veut rien dire. Indiquez l'erreur, et/ou les comportements attendus et obtenus, et donnez un Exemple Complet Minimal qui permet de reproduire le problème.
    La plupart des réponses à vos questions sont déjà dans les FAQs ou les Tutoriels, ou peut-être dans une autre discussion : utilisez la recherche interne.
    Des questions sur Java : consultez le Forum Java. Des questions sur l'EDI Eclipse ou la plateforme Eclipse RCP : consultez le Forum Eclipse.
    Une question correctement posée et rédigée et vous aurez plus de chances de réponses adaptées et rapides.
    N'oubliez pas de mettre vos extraits de code entre balises CODE (Voir Mode d'emploi de l'éditeur de messages).
    Nouveau sur le forum ? Consultez Les Règles du Club.

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

Discussions similaires

  1. Héritage et relation entre les classes filles
    Par h_ayadi dans le forum JPA
    Réponses: 3
    Dernier message: 02/02/2012, 20h02
  2. Réponses: 1
    Dernier message: 17/04/2011, 16h30
  3. Réponses: 6
    Dernier message: 22/07/2010, 15h17
  4. Lien d'héritage non visible dans la classe fille
    Par trotters213 dans le forum C++
    Réponses: 2
    Dernier message: 15/12/2007, 12h47
  5. Réponses: 10
    Dernier message: 20/09/2006, 17h04

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