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 :

[Language]Classe abstraite


Sujet :

Langage Java

  1. #1
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Février 2005
    Messages
    35
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2005
    Messages : 35
    Points : 25
    Points
    25
    Par défaut [Language]Classe abstraite
    Bonjour les amis,

    Je suis en train d'utiliser pour la 1ère fois une classe abstraite.

    Je vous explique mon problème :

    En fait, j'ai créé différentes classes, une pour chaque structures de données (des piles, listes, arbres binaires...) qui dérivent TOUTES de ma classe abstraite.

    J'ai par exemple déclaré une fonction estEgal dans ma classe abstraite. Et donc logiquement en fonction du type, ma fonction attend différents paramètres :
    - un arbre pour tester l'égalité avec un autre arbre
    - une pile pour tester l'égalité avec une autre pile
    - ....

    Mais maintenant j'ai une erreur dans mes classes lors de la compilation, car le compilateur signale que toutes les fonctions estEgal ne sont pas utilisées pour tous les types. Je m'explique : dans ma classe Pile qui dérive de ma classe abstraite, je n'ai pas utilisé la fonction estEgal qui attend comme paramètre un arbre (logique...)

    Je pensais, que comme c'était le même nom de fonction 'estEgal', il n'y aurait pas de problème... Or cela ne semble pas être le cas.

    Qu'est ce que vous pouvez me dire par rapport à ce problème ?
    Est ce que je n'ai pour unique choix que de supprimer ces fonctions de ma classe abstraite ?

    Merci à l'avance pour vos précisions

  2. #2
    Membre expérimenté
    Avatar de zekey
    Profil pro
    Inscrit en
    Février 2005
    Messages
    1 036
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2005
    Messages : 1 036
    Points : 1 403
    Points
    1 403
    Par défaut
    Si je comprend bien tu fais:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    public class abstract Toto{
       public abstract boolean estEgal(Pile pPile);
       public abstract boolean estEgal(Arbre pArbre);
    }
     
    public class Tata extends Toto{
      public abstract boolean estEgal(Pile pPile){
        return true; 
      }
    }
    Et le compilo rale parce que tu n'implementes pas estEgal(Arbre) c'est ca ?
    Si c'est le cas c'est tout a fait normal car une class ne peut devenir concrète (pouvoir faire un new) que si toutes les méthodes abstraites sont implémentées. Ca semble logique.
    En Java une classe ne peut étendre deux classes donc pas moyens de dispatcher tes deux méthodes dans deux classes abstraites.
    Cependant il existe un deuxieme moyen de gerer les contrats (puisque c'est le but des classes abstraites) c'est les interfaces.
    Dans ce cas une classe peut implémenter une ou plusieurs interface.

    C'est à dire

    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 interface I1{
       public abstract boolean estEgal(Pile pPile);
    }
    public interface I2{
       public abstract boolean estEgal(Arbre pArbre);
    }
     
    public class Tata1 implements I1{
      public abstract boolean estEgal(Pile pPile){
        return true; 
      }
    }
     
    public class Tata2 implements I2{
      public abstract boolean estEgal(Arbre pArbre){
        return true; 
      }
    }
     
    public class Tata12 implements I1,I2{
      public abstract boolean estEgal(Arbre pArbre){
        return true; 
      }
      public abstract boolean estEgal(Pile pPile){
        return true; 
      }
    }
    Steve Hostettler
    est ton ami(e) et le tag aussi.

  3. #3
    Membre averti
    Inscrit en
    Août 2005
    Messages
    352
    Détails du profil
    Informations forums :
    Inscription : Août 2005
    Messages : 352
    Points : 427
    Points
    427
    Par défaut
    Faut pas s'embeter pour rien, une seule méthode estEqual suffit :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    public class abstract Toto{
       public abstract boolean estEgal(Object obj);
    }
     
    public class Tata extends Toto{
      public boolean estEgal(Object obj){
        if (this.equals(obj))//vérification de l'identité
            return true;
        if (!this.getClass().equals(obj.getClass()))//vérification de la classe
            return false;
        Tata tata = (Tata)obj;//si on a passé le test précédent, on peut faire la conversion
        //ensuite tu implementes ta comparaison "champ à champ" ou selon se que tu souhaites
      }
    }

  4. #4
    Membre averti Avatar de soad
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2004
    Messages
    520
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : Suisse

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Février 2004
    Messages : 520
    Points : 439
    Points
    439
    Par défaut
    Hello tout le monde...

    Je profite de ce poste pour demander quel est la différence entre une class abstraite et une interface ???

    La class abstraite est hériter et l'interface est implémenter, mais y a-til d'autre différence ?

  5. #5
    Membre expérimenté
    Avatar de zekey
    Profil pro
    Inscrit en
    Février 2005
    Messages
    1 036
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2005
    Messages : 1 036
    Points : 1 403
    Points
    1 403
    Par défaut
    Citation Envoyé par saod
    Hello tout le monde...

    Je profite de ce poste pour demander quel est la différence entre une class abstraite et une interface ???

    La class abstraite est hériter et l'interface est implémenter, mais y a-til d'autre différence ?
    Ben contrairement à C++, l'héritage multiple n'est pas permis en Java.
    Ce qui est plus ou moins le problème ici. L'interface permet de contourner le problème.
    Un autre exemple est le mecanisme de Thread:
    2 méthodes: Implementer Runnable ou etendre Thread. Comme on ne peut étendre 2 classes il ne serait pas possible de créer une Thread qui hérite d'un autre objet pour des raisons de désign si on avait pas le mécanisme d'interface.

    Maintenant la question est: pourquoi les hautes sphrères ont décidé de ne pas permettre l'heritage multiples. Ca franchement je ne sais pas.
    Steve Hostettler
    est ton ami(e) et le tag aussi.

  6. #6
    Membre averti Avatar de soad
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2004
    Messages
    520
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : Suisse

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Février 2004
    Messages : 520
    Points : 439
    Points
    439
    Par défaut
    Citation Envoyé par ze_key
    Ben contrairement à C++, l'héritage multiple n'est pas permis en Java.
    Ce qui est plus ou moins le problème ici. L'interface permet de contourner le problème.
    Donc il n'y a aucune différence entre une classe abstraite et une interface sauf que l'interface on peut en implémenter plusieurs ???

  7. #7
    Membre éprouvé Avatar de leminipouce
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Janvier 2004
    Messages
    754
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Janvier 2004
    Messages : 754
    Points : 1 253
    Points
    1 253
    Par défaut
    Citation Envoyé par ze_key
    Maintenant la question est: pourquoi les hautes sphrères ont décidé de ne pas permettre l'heritage multiples. Ca franchement je ne sais pas.
    Pour des questions pratiques (si mes sources sont bonnes). En gros, l'héritage multiple, c'est des tonnes de problèmes. Ne pas l'autoriser, c'est s'en affranchir.

    Un des problèmes majeur (dont on m'avait parlé) pour l'héritage multiple est le suivant :
    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
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    public class Vehicule{			//Classe abstraite si ça te fait plaisir....
    	int consommation=0;
     
    	public Vehicule(){}
     
    	public int getCoutRevient(){}
    }
     
    public class Voiture extends Vehicule{
    	public Voiture(){
    		super();
    	}
     
    	public int getCoutRevient(){
    		return consommation*2;
    	}
    }
     
    public class Moto extends Vehicule{
    	public Moto(){
    		super();
    	}
     
    	public int getCoutRevient(){
    		return consommation;
    	}
    }
     
    public class HybrideATroisRoues extends Voiture, Moto{
    	public HybrideATroisRoues(){
    		super();
    	}
    }
     
    public void main(){
    	Vehicule[] vehicules=new Vehicule[];
     
    	vehicules[0]=new Voiture();
    	vehicules[1]=new Moto();
    	vehicules[2]=new HybrideATroisRoues();
     
    	for(int i=0; i<3; i++){
    		System.out.println("Prix de revient : "+vehicules[i].getCoutRevient());
    	}
    }
    Dans ce cas, peux-tu me dire quelle méthode getCoupDeRevient() sera utilisé pour la véhicules HybrideATroisRoues ?

    Donc revenons aux sources pour justifier un peu....

    Quand tu hérites d'une classe, tu n'es pas obliger de redéfinir les méthodes. Donc sur un appel depuis une classe fille, la première méthode parente a avoir été défini sera appelée. Si tu étends une classe abstraite, tu ne pourras PAS faire appel à une de ses méthodes sans la redéfinir. Mais tu n'est pas obligé de la redéfinir si tu n'en a pas besoin.

    En revanche, tu es obligé de redéfinir TOUTES les méthodes des TOUTES les interfaces que tu implémentes. Donc si tu veux faire appel à une méthode d'une interface, tu lèves obligatoirement tous les doutes possibles concernant l'appel à une méthode : elle est défini dans le corps de la classe.

    Voilà, j'espère ne pas être un trop mauvais prof

    Citation Envoyé par saod
    Donc il n'y a aucune différence entre une classe abstraite et une interface sauf que l'interface on peut en implémenter plusieurs ???
    Ben si. Et la réponse se trouve dans les quelques lignes si dessus
    Si , et la ont échoué mais pas nous, pensez à dire et cliquez sur . Merci !

    Ici, c'est un forum, pas une foire. Il y a de respectables règles... à respecter !

  8. #8
    Membre expérimenté
    Avatar de zekey
    Profil pro
    Inscrit en
    Février 2005
    Messages
    1 036
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2005
    Messages : 1 036
    Points : 1 403
    Points
    1 403
    Par défaut
    Et pour le problème de base, quelqu'un a une meilleur méthode que plusieurs interfaces ? Enfin meilleur moi je la trouve très bien mais bon si je peux me coucher moi bête....
    Steve Hostettler
    est ton ami(e) et le tag aussi.

  9. #9
    Membre éprouvé Avatar de leminipouce
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Janvier 2004
    Messages
    754
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Janvier 2004
    Messages : 754
    Points : 1 253
    Points
    1 253
    Par défaut
    Et pour revenir au message initial :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    public class abstract Toto{ 
       public abstract boolean estEgal(Toto toto); 
    }
    Après, pour des raisons de propreté et d'éthique de codage, je mettrai en préconditions de mes méthodes estEgal() le fait qu'elles ne doivent accepter en paramètre qu'un objet de leur type.
    Préconditions, ça veut dire que tu fais un test AVANT l'appel à ta méthode sur la validité du paramètre que tu lui fournis.

    Cependant, si tu tiens absolument à faire tes tests à l'intérieur de la méthode (je le dis et je le répète, ça ne rime à rien pour moi...), le code donnée par dlemoing va très bien !

    En gros, dlemoing ta donné la solution, je me contente de remplacer son Object par une classe plus précise
    Si , et la ont échoué mais pas nous, pensez à dire et cliquez sur . Merci !

    Ici, c'est un forum, pas une foire. Il y a de respectables règles... à respecter !

  10. #10
    Membre émérite
    Avatar de xavlours
    Inscrit en
    Février 2004
    Messages
    1 832
    Détails du profil
    Informations forums :
    Inscription : Février 2004
    Messages : 1 832
    Points : 2 410
    Points
    2 410
    Par défaut
    Pour le thread initial : la méthode equals() sert précisément à ce que tu veux faire. Elle se conforme à la solution donnée par dlemoing :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    public abstract class Toto {
      public abstract boolean estEgal(Object o);
    }
    Je te conseille cette solution car c'est ce qui se fait couramment en java pour tester l'égalité des objets. De plus, je te conseille de ne pas utiliser une méthode à toi : ça t'oblige à définir une classe abstraite, et à en tenir compte toi meme.
    L'API standard utilise fréquemment la méthode equals() définie dans Object. Elle sert exactement à ça, et est utilisée notamment dans les HashMap ou HashSet. Je te conseille d'utiliser cette méthode, cela t'évite de définir une classe abstraite et de redéfinir tes conteneurs.

    Pour le troll, je considère plus une interface comme un contrat : une classe s'engage à implémenter une méthode avec une signature particulière. Mais ca ne lui pose aucune contrainte sur ses attributs, ou quoi que ce soit, et ca ne lui donne aucune méthode supplémentaire, à l'inverse de l'héritage d'une classe abstraite.

    C'est comme cela que j'aborde la question de savoir si il me faut une classe abstraite ou une interface.
    "Le bon ni le mauvais ne me feraient de peine si si si je savais que j'en aurais l'étrenne." B.V.
    Non au langage SMS ! Je ne répondrai pas aux questions techniques par MP.
    Eclipse : News, FAQ, Cours, Livres, Blogs.Et moi.

  11. #11
    Membre confirmé Avatar de anitshka
    Inscrit en
    Mai 2004
    Messages
    624
    Détails du profil
    Informations forums :
    Inscription : Mai 2004
    Messages : 624
    Points : 605
    Points
    605
    Par défaut
    Citation Envoyé par ze_key
    Maintenant la question est: pourquoi les hautes sphrères ont décidé de ne pas permettre l'heritage multiples. Ca franchement je ne sais pas.
    avec l'héritage multiple..

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    MaClassMere1{
    void methode(double parm1){...je fais un autre truc...};
    }
     
    MaClassMere2{
    void methode(double parm2){...je fais un autre truc...};
    }
     
    MaClasseFille extend MaClassMere1 et MaClassMere2 {
    void utilisation(){
      super.methode(30.6); -> mais quelle methode va t elle choisir?
    }
    }
    d'ou on enlève tous les conflits en forceant l'héritage simple
    Ni Dieu, ni maître, mais des frites bordel!

Discussions similaires

  1. [Language]classe abstraite
    Par mikees dans le forum Langage
    Réponses: 14
    Dernier message: 15/11/2005, 23h32
  2. Réponses: 2
    Dernier message: 27/03/2005, 16h09
  3. [Debutant][Conception] Classes abstraites et interface.
    Par SirDarken dans le forum Langage
    Réponses: 4
    Dernier message: 29/10/2004, 00h02
  4. Classe abstraite / MVC
    Par caramel dans le forum MVC
    Réponses: 5
    Dernier message: 01/04/2003, 09h27
  5. pb constructeurs classes dérivant classe abstraite
    Par Cornell dans le forum Langage
    Réponses: 2
    Dernier message: 10/02/2003, 19h02

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