JavaRush /Blog Java /Random-FR /Principes de la POO

Principes de la POO

Publié dans le groupe Random-FR
Bonjour! Vous êtes-vous déjà demandé pourquoi Java est conçu ainsi ? Dans le sens où vous créez des classes, basées sur elles - les objets, les classes ont des méthodes, etc. Mais pourquoi la structure du langage est-elle telle que les programmes sont constitués de classes et d’objets, et non d’autre chose ? Pourquoi la notion d’« objet » a-t-elle été inventée et mise au premier plan ? Tous les langages fonctionnent-ils de cette façon et, sinon, quels avantages cela apporte-t-il à Java ? Comme vous pouvez le constater, il y a beaucoup de questions :) Essayons de répondre à chacune d'elles dans la conférence d'aujourd'hui.

Principes de la POO :

  1. Héritage
  2. Abstraction
  3. Encapsulation
  4. Polymorphisme

Qu'est-ce que la programmation orientée objet (POO)

Bien entendu, Java est constitué d’objets et de classes pour une raison. Ce n’est pas un caprice de ses créateurs, ni même leur invention. Il existe de nombreux autres langages basés sur des objets. Le premier langage de ce type s’appelait Simula et a été inventé dans les années 1960 en Norvège. Entre autres choses, Simula a introduit les concepts de « classe » et de « méthode ». Principes de programmation orientée objet - 2
Kristen Nygaard et Ole Johan Dahl - créateurs de Simula
Il semblerait que Simula soit un langage ancien selon les normes de programmation, mais leur lien « familial » avec Java est visible à l'œil nu. Très probablement, vous pouvez facilement lire le code qui y est écrit et expliquer en termes généraux ce qu'il fait :)
Begin
  Class Rectangle (Width, Height); Real Width, Height;

   Begin
      Real Area, Perimeter;

      Procedure Update;
      Begin
        Area := Width * Height;
              OutText("Rectangle is updating, Area = "); OutFix(Area,2,8); OutImage;
        Perimeter := 2*(Width + Height);
              OutText("Rectangle is updating, Perimeter = "); OutFix(Perimeter,2,8); OutImage;
      End of Update;

      Update;
      OutText("Rectangle created: "); OutFix(Width,2,6);
      OutFix(Height,2,6); OutImage;
   End of Rectangle;

       Rectangle Class ColouredRectangle (Color); Text Color;

  Begin
      OutText("ColouredRectangle created, color = "); OutText(Color);
      OutImage;
        End of ColouredRectangle;


         Ref(Rectangle) Cr;
   Cr :- New ColouredRectangle(10, 20, "Green");
End;
L'exemple de code est tiré de l'article Simula - 50 ans de POO . Comme vous pouvez le constater, Java et son ancêtre ne sont pas si différents l'un de l'autre :) Cela est dû au fait que l'apparition de Simula a marqué la naissance d'un nouveau concept : la programmation orientée objet. Wikipédia donne la définition suivante de la POO : La programmation orientée objet (POO) est une méthodologie de programmation basée sur la représentation d'un programme comme une collection d'objets, dont chacun est une instance d'une classe spécifique, et les classes forment une hiérarchie d'héritage. C'est, à mon avis, très réussi. Vous avez récemment commencé à apprendre Java, mais il n'y a pratiquement aucun mot qui vous soit inconnu :) Aujourd'hui, la POO est la méthodologie de programmation la plus courante. Outre Java, les principes de la POO sont utilisés dans de nombreux langages populaires dont vous avez peut-être entendu parler. Il s'agit du C++ (il est activement utilisé par les développeurs de jeux informatiques), d'Objective-C et de Swift (ils écrivent des programmes pour les appareils Apple), de Python (le plus demandé en apprentissage automatique), de PHP (l'un des langages de développement Web les plus populaires), JavaScript (plus simple, dites ce qu'ils ne font pas dessus) et bien d'autres. Au fait, quels sont ces « principes » de la POO ? Disons-le plus en détail.

Principes de la POO

C'est la base. 4 fonctionnalités principales qui forment ensemble le paradigme de la programmation orientée objet. Les comprendre est la clé pour devenir un programmeur performant. Principes de programmation orientée objet - 3

Principe 1. Héritage

La bonne nouvelle est que vous connaissez déjà certains principes de la POO ! :) Nous avons déjà rencontré l'héritage à plusieurs reprises lors de cours, et nous avons eu le temps de travailler avec. L'héritage est un mécanisme qui vous permet de décrire une nouvelle classe basée sur une classe existante (parente). Dans ce cas, les propriétés et fonctionnalités de la classe parent sont empruntées par la nouvelle classe. Pourquoi l’héritage est-il nécessaire et quels avantages apporte-t-il ? Tout d’abord, la réutilisation du code. Les champs et méthodes décrits dans les classes parentes peuvent être utilisés dans les classes descendantes. Si tous les types de voitures ont 10 champs communs et 5 méthodes identiques, il vous suffit de les mettre dans la classe parent Auto. Vous pouvez les utiliser dans les classes descendantes sans aucun problème. De solides avantages : à la fois quantitatifs (moins de code) et, par conséquent, qualitativement (les cours deviennent beaucoup plus simples). Dans le même temps, le mécanisme d'héritage est très flexible et vous pouvez ajouter séparément les fonctionnalités manquantes dans les descendants (certains champs ou comportements spécifiques à une classe particulière). En général, comme dans la vie ordinaire : nous sommes tous semblables à nos parents à certains égards, mais différents d'eux à certains égards :)

Principe 2. Abstraction

C'est un principe très simple. L'abstraction signifie mettre en évidence les caractéristiques principales et les plus significatives d'un objet et vice versa, en éliminant les caractéristiques secondaires et insignifiantes. Ne réinventons pas la roue et rappelons-nous un exemple tiré d'une vieille conférence sur les cours. Disons que nous créons un classeur des employés de l'entreprise. Pour créer des objets employés, nous avons écrit une classe Employee. Quelles caractéristiques sont importantes pour leur description dans le dossier de l’entreprise ? Nom complet, date de naissance, numéro de sécurité sociale, numéro d'identification fiscale. Mais il est peu probable que dans une carte de ce type nous ayons besoin de sa taille, de la couleur de ses yeux et de ses cheveux. L'entreprise n'a pas besoin de ces informations sur l'employé. Par conséquent, pour la classe, nous Employeedéfinirons les variables String name, et , et nous abandonnerons les informations qui ne nous sont pas nécessaires, comme la couleur des yeux, et les résumerons. Mais si l’on crée un catalogue de modèles photo pour une agence, la situation change radicalement. Pour décrire un mannequin, la taille, la couleur des yeux et la couleur des cheveux sont très importantes pour nous, mais le numéro TIN n'est pas nécessaire. Par conséquent, dans la classe , nous créons des variables , , . int ageint socialInsuranceNumberint taxNumberModelString heightString hairString eyes

Principe 3 : Encapsulation

Nous l'avons déjà rencontré. L'encapsulation en Java signifie limiter l'accès aux données et la possibilité de les modifier. Comme vous pouvez le constater, il est basé sur le mot « capsule ». Dans cette « capsule », nous cachons des données importantes pour nous que nous ne voulons pas que quiconque change. Un exemple simple de la vie. Vous avez un prénom et un nom. Tous ceux que vous connaissez les connaissent. Mais ils n’ont pas accès pour changer votre prénom et votre nom. Ce processus, pourrait-on dire, est « encapsulé » dans le bureau des passeports : vous ne pouvez y changer que votre prénom et votre nom, et vous seul pouvez le faire. Les autres « utilisateurs » ont accès en lecture seule à votre prénom et votre nom :) Un autre exemple est l'argent dans votre appartement. Les laisser bien en vue au milieu de la pièce n’est pas une bonne idée. Tout « utilisateur » (une personne qui se présente chez vous) pourra modifier le numéro de votre argent, c'est-à-dire Les ramasser. Il vaut mieux les encapsuler dans un coffre-fort. Vous seul y aurez accès et uniquement avec un code spécial. Des exemples évidents d'encapsulation avec lesquels vous avez déjà travaillé sont les modificateurs d'accès ( private, publicetc.) et les getter-setters. Si le champ ageclass Catn’est pas encapsulé, n’importe qui peut écrire :
Cat.age = -1000;
Et le mécanisme d'encapsulation nous permet de protéger le champ ageavec une méthode setter, dans laquelle nous pouvons vérifier que l'âge ne peut pas être un nombre négatif.

Principe 4. Polymorphisme

Le polymorphisme est la capacité de traiter plusieurs types comme s'il s'agissait du même type. Dans ce cas, le comportement des objets sera différent selon le type auquel ils appartiennent. Cela semble un peu compliqué ? Voyons cela maintenant. Prenons l'exemple le plus simple : les animaux. Créons une classe Animalavec une seule méthode - voice(), et deux de ses descendants - Catet Dog.
public class Animal {

   public void voice() {

       System.out.println("Voice!");
   }
}

public class Dog extends Animal {


   @Override
   public void voice() {
       System.out.println("Bow-wow!");
   }
}

public class Cat extends Animal {

   @Override
   public void voice() {
       System.out.println("Meow!");
   }
}
Essayons maintenant de créer un lien Animalet de lui attribuer un objet Dog.
public class Main {

   public static void main(String[] args) {

       Animal dog = new Dog();
       dog.voice();
   }
}
Selon vous, quelle méthode sera appelée ? Animal.voice()ou Dog.voice()? La méthode de classe s'appellera Dog: Woof-woof ! Nous avons créé une référence Animal, mais l'objet se comporte comme Dog. Si nécessaire, il peut se comporter comme un chat, un cheval ou un autre animal. L'essentiel est d'attribuer une référence d'un type général Animalà un objet d'une classe descendante spécifique. C'est logique, car tous les chiens sont des animaux. C’est ce que nous voulions dire lorsque nous disions « les objets se comporteront différemment selon leur type ». Si nous devions créer un objet Cat-
public static void main(String[] args) {

   Animal cat = new Cat();
   cat.voice();
}
la méthode voice()afficherait "Meow!" Que signifie « la capacité de travailler avec plusieurs types comme s’il s’agissait du même type » ? C'est également assez simple. Imaginons que nous créions un salon de coiffure pour animaux. Notre salon de coiffure doit être capable de couper tous les animaux, nous allons donc créer une méthode shear()(« coupe ») avec un paramètre Animal- l'animal que nous allons couper.
public class AnimalBarbershop {

   public void shear(Animal animal) {

       System.out.println("The haircut is ready!");
   }
}
Et maintenant nous pouvons passer shearà la fois des objets Catet des objets à la méthode Dog!
public static void main(String[] args) {

   Cat cat = new Cat();
   Dog dog = new Dog();

   AnimalBarbershop barbershop = new AnimalBarbershop();

   barbershop.shear(cat);
   barbershop.shear(dog);
}
Voici un exemple clair : la classe AnimalBarbershopfonctionne avec les types Catcomme Dogs’il s’agissait du même type. En même temps, ils ont des comportements Catdifférents Dog: ils utilisent leur voix différemment.

Raisons de l'émergence de la POO

Pourquoi ce nouveau concept de programmation - la POO - est-il apparu ? Les programmeurs disposaient d’outils qui fonctionnaient : des langages procéduraux, par exemple. Qu’est-ce qui les a poussés à inventer quelque chose de fondamentalement nouveau ? Tout d’abord, la complexité des tâches auxquelles ils étaient confrontés. S'il y a 60 ans la tâche d'un programmeur ressemblait à « calculer une équation mathématique telle ou telle », cela peut maintenant ressembler à « mettre en œuvre 7 fins différentes pour le jeu STALKER en fonction des décisions prises par l'utilisateur aux moments de jeu A, B, C, D ». , E, F et des combinaisons de ces solutions." Comme vous pouvez le constater, les tâches sont clairement devenues plus complexes au cours des dernières décennies. Cela signifie que les types de données sont devenus plus complexes. C'est une autre raison de l'émergence de la POO. L'exemple avec l'équation peut être facilement résolu en utilisant des primitives ordinaires ; aucun objet n'est nécessaire ici. Mais il sera difficile de décrire le problème des fins du jeu sans utiliser certaines classes que vous avez inventées. Mais en même temps, il est assez simple de le décrire en classes et en objets : on aura évidemment besoin de la classe Game, de la classe Stalker, de la classe Ending, de la classe Player's Decision, de la classe Game Moment, etc. Autrement dit, même sans commencer à résoudre un problème, nous pouvons facilement imaginer dans nos têtes des « esquisses » de sa solution. La complexité croissante des problèmes a obligé les programmeurs à diviser le problème en plusieurs parties. Mais en programmation procédurale, ce n’était pas si simple. Et très souvent, le programme était un « arbre » composé d'un tas de branches avec toutes les options possibles pour son fonctionnement. Selon certaines conditions, le programme a été exécuté dans une branche ou une autre. Pour les petits programmes, cette option était pratique, mais diviser une tâche importante en plusieurs parties était très difficile. Ce besoin est devenu une autre raison de l'émergence de la POO. Ce concept a donné aux programmeurs la possibilité de diviser un programme en un ensemble de « modules » de classes, dont chacun effectuait sa propre partie du travail. Tous les objets, interagissant les uns avec les autres, constituent le travail de notre programme. De plus, le code que nous écrivons peut être réutilisé ailleurs dans le programme, ce qui permet également de gagner beaucoup de temps.
Commentaires
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION