Partage
  • Partager sur Facebook
  • Partager sur Twitter

Incompréhension cours classe abstraite

Sujet résolu
    10 décembre 2018 à 12:56:35

    Bonjour à tous, 

    Dans ce chapitre https://openclassrooms.com/fr/courses/26832-apprenez-a-programmer-en-java/21973-les-classes-abstraites-et-les-interfaces , on nous donne ce code : 

    Classe Animal : 

    abstract class Animal {
    
      protected String couleur;
      protected int poids;
    
      protected void manger(){
        System.out.println("Je mange de la viande.");
      }
            
      protected void boire(){
        System.out.println("Je bois de l'eau !");
      }
            
      abstract void deplacement();
            
      abstract void crier();
            
      public String toString(){
        String str = "Je suis un objet de la " + this.getClass() + ", je suis " + this.couleur + ", je pèse " + this.poids;
        return str;
      }        
    }

    Classe Canin : 

    public abstract class Canin extends Animal {
      void deplacement() {
        System.out.println("Je me déplace en meute !");
      }
    }

    Classe  Chien : 

    public class Chien extends Canin {
     
      public Chien(){
    
      }
    
      public Chien(String couleur, int poids){
        this.couleur = couleur;
        this.poids = poids;
      }       
    
      void crier() {
        System.out.println("J'aboie sans raison !");
      } 
    }



    Ma question : cette dernière classe contient une méthode abstraite, pourquoi n'est-elle pas déclarée abstraite ?

    Voili voilou, merci d'avance  :-° 

    -
    Edité par Saloon 10 décembre 2018 à 13:36:22

    • Partager sur Facebook
    • Partager sur Twitter
      10 décembre 2018 à 15:21:18

      Bonjour à toi.

      Quand tu dis quand la classe Chient contient une méthode abstraite, tu parles de la méthode crier() j'imagine ?

      Si tu penses que cette méthode est abstraite, alors il y a effectivement un petit truc qui t'échappe ^^

      Une classe est abstraite quand elle contient au moins une méthode abstraite dedans. Jusque là ca va.

      Une classe abstraite ne peut pas être instanciée directement. On ne peut instancier que des classes non abstraites qui héritent de la classe abstraite en question. Donc pas de "new Animal();" possible. Par contre, un "new Chien();" c'est ok !

      Une méthode est abstraite quand on déclare son type de retour, son nom, ses paramètres, mais sans définir ce qu'elle fait exactement. Pourquoi ? Parce que suivant la classe qui héritera de cette méthode abstraite, elle fera des choses différentes.

      Avec l'exemple du cours, on part du principe qu'un animal crie et se déplacement dans tous les cas. Sauf que suivant l'animal en question, il fera des cris différents et se déplacement différemment. Donc tant qu'on n'a pas d'info sur comment l'animal crie et comment il se déplacement, on ne peut pas en créer. il faut les définir avant.

      Si je crée une classe Chien qui hérite de Animal, je n'ai pas besoin de redéfinir les méthodes de Animal non abstraites, il en hérite quoi (manger, boire dans ce cas la). Je pense que ca ca va. Par contre, on est obligé de définir les méthodes abstraites d'Animal : crier et déplacement. Et donc dans cette classe chien, on va devoir obligatoirement dire ce que fait la méthode crier, et la méthode déplacement.

      Et une fois que c'est fait, et bien les méthodes crier et déplacement dans chien ne sont pas abstraites, vu qu'on sait ce qu'elles font.

      Et si Chien n'a pas de méthode abstraire, alors la classe n'est pas abstraite.

      La subtilité dans l'exemple du cours, c'est la classe Canin, qui elle est abstraite, alors que quand on la regarde, elle ne contient pas de méthode abstraite.

      Pourquoi est elle abstraite dans ce cas ? Car elle ne définit pas encore ce que fait "crier", on a juste préciser que tous les canins se déplacent en meute. Par contre, tous les canins ne crient pas de la même manière. Donc tant que la méthode crier n'est pas définie, alors la classe reste abstraite.

      -
      Edité par Tiffado 10 décembre 2018 à 15:25:00

      • Partager sur Facebook
      • Partager sur Twitter
        11 décembre 2018 à 2:13:42

        C'est parfaitement clair, merci beaucoup !
        • Partager sur Facebook
        • Partager sur Twitter
          13 décembre 2018 à 11:46:00

          Bonjour,

          En fait je crois que je ne comprends toujours pas : 

          Dans la deuxième partie du chapitre, on nous donne : 

          public abstract class Personnage {
          
            protected String armes = "", chaussure = "", sacDeSoin = "";
          
            public void seDeplacer(){
              System.out.println("Je me déplace à pied.");
            }
          
            public void combattre(){
              System.out.println("Je ne combats PAS !");
            }
          
            public void soigner(){
              System.out.println("Je ne soigne pas.");
            }
          	
            protected void setArmes(String armes) {
              this.armes = armes;
            }
          
            protected void setChaussure(String chaussure) {
              this.chaussure = chaussure;
            }
          
            protected void setSacDeSoin(String sacDeSoin) {
              this.sacDeSoin = sacDeSoin;
            }
          }

          Ici, des comportements "par défaut" des méthodes combattre(), soigner() etc... sont définies, je dis bien définies ! 

          Toutes les méthodes des classes enfants sont définies dans cette classe mère.

          Donc, pourquoi est-elle abstraite ?

          Merci bien ! :D

          • Partager sur Facebook
          • Partager sur Twitter
            13 décembre 2018 à 11:50:08

            Et bien, sur le principe, elle est abstraite car on ne veut pas qu'on instancie un objet de type Personnage, mais uniquement des classes qui en héritent.

            Mais j'avoue qu'une classe abstraite sans méthode abstraite, c'est pas courant.

            Il s'agit la d'un comportement par défaut, mais qui seront override dans les classes filles. Ou alors les classes filles auront d'autres méthodes accessibles.

            Typiquement :

            public class Cavalier extends Personnage {
            
            	@Override
            	public void seDeplacer(){
            		System.out.println("Je me déplace à cheval.");
            	}
            }


            Du coup, my bad, j'ai dit une bêtise en disant :

            Une classe est abstraite quand elle contient au moins une méthode abstraite dedans. 

            Ce n'est pas obligatoire.

            je vois dans le cours qu'il n'y a pas d'Override, l'explication ici :

            https://openclassrooms.com/forum/sujet/signification-override-21028


            -
            Edité par Tiffado 13 décembre 2018 à 11:57:13

            • Partager sur Facebook
            • Partager sur Twitter
              13 décembre 2018 à 11:54:34

              D'accord donc fondamentalement pour bien savoir quand une classe doit être abstraite, on pourrait résumer avec : 

              "On ne doit pas pouvoir instancier d'objet en utilisant cette classe => rendons-la abstraite", right ?

              • Partager sur Facebook
              • Partager sur Twitter
                13 décembre 2018 à 11:59:18

                C'est ça.

                Cela dit, une interface non plus ne pas être être instancier, donc il faut quand même les utiliser à bon escient ^^

                En vrai, il y a quand même tout le résumé en bas de la page du cours, n'hésite pas à relire ca :p

                -
                Edité par Tiffado 13 décembre 2018 à 12:01:14

                • Partager sur Facebook
                • Partager sur Twitter
                  13 décembre 2018 à 12:02:27

                  Oui. 

                  D'ailleurs, comment savoir laquelle des deux utiliser ? 

                  Moi bêtement je me dis "si c'est 100% abstrait, j'en fais une interface", cela suffit-il pour choisir intelligemment ? 

                  Tiffado a écrit:

                  En vrai, il y a quand même tout le résumé en bas de la page du cours, n'hésite pas à relire ca :p

                  -
                  Edité par Tiffado il y a moins de 30s


                  Allez c'est d'accord j'arrête avec mes questions idiotes, on verra bien en pratiquant ;) 

                  Merci à toi !

                  -
                  Edité par Saloon 13 décembre 2018 à 12:04:22

                  • Partager sur Facebook
                  • Partager sur Twitter
                    13 décembre 2018 à 12:09:12

                    Je dirais bêtement que par défaut, tu fais une interface, mais si tu te rends compte pour que tu peux factoriser une méthode, alors tu transformes ton interface en classe abstraite.

                    Sauf que bon, ce n'est pas si simple que ça car dans le fond, une classe peut implémenter plusieurs interfaces, mais ne peut hériter que d'une seule classe.

                    Donc ca va demander plus de réflexion que ça quand même si tu sais que tu vas devoir mettre en place un système de classes relativement complexe. Pour le coup, j'ai pas de solution magique, je pense que ca va être au cas par cas, ou alors attendre que quelqu'un de plus doué que moi réponde à ta question x)

                    PS : ne pas oublier qu'une classe abstraite pour implémenter une interface, donc les 2 ne sont pas incompatibles non plus.

                    • Partager sur Facebook
                    • Partager sur Twitter

                    Incompréhension cours classe abstraite

                    × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                    × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
                    • Editeur
                    • Markdown