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

Langage Java Discussion :

instanceof ou mauvais polymorphisme ? [Débat]


Sujet :

Langage Java

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre Expert Avatar de Djakisback
    Profil pro
    Inscrit en
    Février 2005
    Messages
    2 023
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2005
    Messages : 2 023
    Par défaut instanceof ou mauvais polymorphisme ?
    Salut, j'ai un problème de base mais je ne comprends pas très bien le mécanisme à adopter, si quelqu'un pouvait me guider. J'ai par exemple, 3 classes :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    public class SolidCircle extends Solid {
    	public boolean collideWith(SolidCircle circle) {...}
    }
     
    public class SolidRectangle extends Solid {
    	public boolean collideWith(SolidRectangle circle) {...}
    }
    Comment on fait pour récupérer et appeler la fonction adéquate dans le cas suivant, j'ai donc un vecteur qui contient des SolidRectangle et des SolidCircle :

    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
    public Vector movableSolids; // D'ailleurs il me semblait que Vector était pas trop optimisé pourtant c'est la seule structure que propose le CLDC 1.1 du J2ME
     
    static public void computeCollisions() {
    		for (int i = 0, solidsSize = PEngine.movableSolids.size(); i < solidsSize; i++) {
    			Solid solid1 = ((Solid) (PEngine.movableSolids.elementAt(i)));
    			for (int j = i + 1, solidsSize2 = PEngine.movableSolids.size(); j < solidsSize2; j++) {
    				Solid solid2 = ((Solid) (PEngine.movableSolids.elementAt(j)));
    				if (solid1.collideWith(solid2)) {
    					PEngine.computeCollisionResponse(solid1, solid2);
    				}
    			}
    		}
    	}
     
    	static public void computeCollisionResponse(SolidCircle circle1, SolidCircle circle2) {..}
     
    	static public void computeCollisionResponse(SolidRectangle rectangle1, SolidRectangle rectangle2) {...}
    J'ai pensé définir une méthode abstraite collideWith(Solid s) dans Solid mais ensuite il faut que j'en implémente une aussi dans SolidRectange et dans SolidCircle, ce qui n'a aucune utilité. Ma question est donc, comment appeler les bonnes méthodes collideWith et computeCollisionResponse, en fonction des types réels des instances, j'imagine qu'il y a moyen de faire ca sans instanceof ?
    Merci d'avance ^^

  2. #2
    Membre Expert Avatar de willoi
    Profil pro
    Développeur informatique
    Inscrit en
    Décembre 2006
    Messages
    1 355
    Détails du profil
    Informations personnelles :
    Âge : 52
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Décembre 2006
    Messages : 1 355
    Par défaut
    A mon avis cette ligne :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    PEngine.computeCollisionResponse(solid1, solid2);
    doit te donner une erreur de compilation.Car tu passe les parametres Solid, Solid a ta methode et celle ci n'existe pas.

    Donc une solution peut etre d'utiliser instanceof puis un casting a la classe adequate.

    Ou sinon implementer des methodes au niveau de tes classes SolidRectangle et SolidCircle.
    Exemple :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    solid1.computeCollisionResponse(solid2);
    et creer une methode dans ta classe Solid :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    computeCollisionResponse(Solid solid);

  3. #3
    Membre confirmé
    Inscrit en
    Juillet 2006
    Messages
    113
    Détails du profil
    Informations forums :
    Inscription : Juillet 2006
    Messages : 113
    Par défaut
    à mon avis tu ajoute ces deux method dans tes class, et comme ça seulon le type des parametre java va savoire quel méthod utiliser.


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    public class SolidCircle extends Solid {
    	public boolean collideWith(SolidCircle circle) {...}
            public boolean collideWith(SolidRectangle rectangle) {...}
    }
     
    public class SolidRectangle extends Solid {
    	public boolean collideWith(SolidRectangle rectangle) {...}
            public boolean collideWith(SolidCircle circle) {...}
    }
    et aussi dans l'autre classe il faut ajouter les deux methodes:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    static public void computeCollisionResponse(SolidCircle circle, SolidCircle rectangle) {..}
    static public void computeCollisionResponse(SolidRectangle rectangle,  SolidCircle circle) {...}
    ou à mon avis je dit de n'importe quoi. pour ce deusiéme probléme il faut peut etre faire comme ce qu' à dit "willoi"

    en tous cas, tu doit développer deux methodes
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    computeCollisionResponse(Solid solid);
    dans chaque class (circle et rectangle)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    public class SolidCircle extends Solid {
    	computeCollisionResponse(SolidCircle circle){...}
            computeCollisionResponse(SolidRectangle rectangle){...}
    }
     
    public class SolidRectangle extends Solid {
    	computeCollisionResponse(SolidCircle circle){...}
            computeCollisionResponse(SolidRectangle rectangle){...}
    }

  4. #4
    Membre expérimenté
    Inscrit en
    Mai 2007
    Messages
    335
    Détails du profil
    Informations forums :
    Inscription : Mai 2007
    Messages : 335
    Par défaut
    Bonjour,
    je vois bien une solution simple:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    public abstract class Solid {
    	public final boolean collideWith(Solid solid) {
                 if (solid instanceof SolidCircle) return collideWith((SolidCircle) solid);
                 if (solid instanceof SolidRectangle) return collideWith((SolidRectangle) solid);
                return false;
            }
     
      protected abstract boolean collideWith(SolidCircle circle);
      protected abstract boolean collideWith(SolidRectangle rectangle);
    }
    parce que le polymorphisme ne s'applique pas sur la surcharge: il y aurais peut-être un moyen de faire du vrai polymorphisme en extrayant des méthodes dans des stratégies ou des Visitor, mais ça deviendrais over-compliqué.

  5. #5
    Membre chevronné
    Profil pro
    Inscrit en
    Janvier 2006
    Messages
    365
    Détails du profil
    Informations personnelles :
    Localisation : Maroc

    Informations forums :
    Inscription : Janvier 2006
    Messages : 365
    Par défaut
    Bonjour,
    Moi je préférerais plutôt ceci :
    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
    25
    26
    27
    28
     
    public abstract class Solid {
        public abstract boolean collideWith(Solid solid);
    }
     
    public class SolidCircle extends Solid {
        public boolean collideWith(Solid solid) {
             if (! solid instanceof SolidCircle)
                   return false;
     
            // sinon faire le traitement spécifique aux objets SolidCircle
           // et retourner "true" ou "false" selon le résultat du traitement
           SolidCircle circle = (SolidCircle)solid;
            ...
        }
    }
     
    public class SolidRectangle extends Solid {
        public boolean collideWith(Solid solid) {
             if (! solid instanceof SolidRectangle)
                   return false;
     
            // sinon faire le traitement spécifique aux objets SolidRectangle
           // et retourner "true" ou "false" selon le résultat du traitement
           SolidRectangle rect = (SolidRectangle)solid;
            ...
        }
    }
    Ceci a l'avantage de conserver le caractère polymorphique de la méthode collideWith() et permet d'ajouter de nouvelle sous-classes de la classe Solid sans affecter cette dernière.

  6. #6
    Membre expérimenté
    Inscrit en
    Mai 2007
    Messages
    335
    Détails du profil
    Informations forums :
    Inscription : Mai 2007
    Messages : 335
    Par défaut
    C'est vrai qu'on est obligé de modifier la classe abstraite pour chaque classe ajoutée, mais tu oublie un point
    ce code est faux:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
        public boolean collideWith(Solid solid) {
             if (! solid instanceof SolidRectangle)
                   return false;
    car un rectangle peut être en collision avec un cercle, et de même si on ajoute un SolidTriangle, il faudra revoir les classes cercle et rectangle pour gérer les collisions Triangle-cercle et triangle-rectangle.

    pour bien faire il faudrait des instance d'opérateur binaire isCollision(Solid,Solid) , surchargés pour chaque type de couple Solid-Solid (un peu comme un Comparator), ce qui trop compliqué pour un cas simple comme celui-ci.

Discussions similaires

  1. instanceof c'est mauvais?
    Par pongping dans le forum Langage
    Réponses: 33
    Dernier message: 20/05/2007, 19h39
  2. Mauvais indicateur de connection
    Par calvin dans le forum Hibernate
    Réponses: 15
    Dernier message: 24/05/2004, 12h03
  3. [Tomcat][JSP] Mauvais fonctionnement
    Par gandalf_le_blanc dans le forum Tomcat et TomEE
    Réponses: 47
    Dernier message: 26/04/2004, 13h07
  4. Mauvais noms de colonnes lors d'une requête
    Par nmathon dans le forum Bases de données
    Réponses: 2
    Dernier message: 09/04/2004, 07h27
  5. mauvais code
    Par moumou dans le forum Autres SGBD
    Réponses: 3
    Dernier message: 17/04/2003, 15h56

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