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

Principes de la POO

Publié dans le groupe Random-FR
Java est un langage orienté objet. Cela signifie que vous devez écrire des programmes Java en utilisant un style orienté objet. Et ce style est basé sur l'utilisation d'objets et de classes dans le programme.

Principes de base de la POO :

Principes de la POO - 1Essayons, à l'aide d'exemples, de comprendre ce que sont les classes et les objets, ainsi que comment appliquer dans la pratique les principes de base de la POO : abstraction, héritage, polymorphisme et encapsulation.

Qu'est-ce qu'un objet ?

Le monde dans lequel nous vivons est constitué d'objets. Si nous regardons autour de nous, nous verrons que nous sommes entourés de maisons, d'arbres, de voitures, de meubles, de vaisselle, d'ordinateurs. Tous ces éléments sont des objets et chacun d’eux possède un ensemble de caractéristiques, de comportement et d’objectif spécifiques. Nous sommes habitués aux objets et nous les utilisons toujours à des fins très précises. Par exemple, si nous devons nous rendre au travail, nous utilisons une voiture, si nous voulons manger, nous utilisons de la vaisselle et si nous avons besoin de nous détendre, nous avons besoin d'un canapé confortable. Une personne est habituée à penser objectivement pour résoudre les problèmes de la vie quotidienne. C'était l'une des raisons pour lesquelles on utilisait des objets dans la programmation, et cette approche de la création de programmes était appelée orientée objet. Donnons un exemple. Imaginez que vous ayez développé un nouveau modèle de téléphone et que vous souhaitiez lancer sa production en série. En tant que concepteur de téléphone, vous savez à quoi il sert, comment il fonctionnera et de quelles pièces il sera composé (boîtier, microphone, haut-parleur, fils, boutons, etc.). Cependant, vous seul savez comment connecter ces pièces. Cependant, vous n'envisagez pas de produire des téléphones personnellement, pour cela vous disposez de toute une équipe d'employés. Pour que vous n'ayez pas à expliquer à chaque fois comment connecter les pièces du téléphone, et pour que tous les téléphones en production soient identiques, avant de commencer à les produire, vous devrez réaliser un dessin sous la forme d'un description de la structure du téléphone. En POO, une telle description, dessin, diagramme ou modèle est appelé une classe à partir de laquelle un objet est créé lors de l'exécution du programme. Une classe est une description d'un objet qui n'a pas encore été créé, comme un modèle général composé de champs, de méthodes et d'un constructeur, et un objet est une instance d'une classe créée sur la base de cette description.

Abstraction POO

Réfléchissons maintenant à la manière dont nous pouvons passer d'un objet du monde réel à un objet dans un programme, en prenant le téléphone comme exemple. L'histoire de ce moyen de communication dépasse 100 ans et le téléphone moderne, contrairement à son prédécesseur du XIXe siècle, est un appareil beaucoup plus complexe. Lorsque nous utilisons un téléphone, nous ne pensons pas à sa structure ni aux processus qui s’y déroulent. Nous utilisons simplement les fonctions fournies par les développeurs du téléphone - boutons ou écran tactile pour sélectionner un numéro et passer des appels. L'une des premières interfaces téléphoniques était un bouton que l'on tournait pour passer un appel. Bien sûr, ce n’était pas très pratique. Néanmoins, la poignée remplit correctement sa fonction. Si vous regardez le téléphone le plus moderne et le tout premier, vous pouvez immédiatement identifier les détails les plus importants qui sont importants à la fois pour un appareil de la fin du 19e siècle et pour un smartphone ultramoderne. Il s’agit de passer un appel (composer un numéro) et de recevoir un appel. Essentiellement, c’est ce qui fait d’un téléphone un téléphone et non autre chose. Nous avons maintenant appliqué le principe de la POO : mettre en évidence les caractéristiques et les informations les plus importantes sur un objet. Ce principe de la POO est appelé abstraction. L'abstraction en POO peut également être définie comme un moyen de représenter des éléments d'un problème du monde réel sous forme d'objets dans un programme. L'abstraction est toujours associée à la généralisation de certaines informations sur les propriétés d'objets ou d'objets, l'essentiel est donc de séparer les informations significatives des informations insignifiantes dans le contexte du problème à résoudre. Dans ce cas, il peut y avoir plusieurs niveaux d’abstraction. Essayons d'appliquer le principe d'abstraction à nos téléphones. Tout d’abord, soulignons les types de téléphones les plus courants depuis les débuts jusqu’à nos jours. Par exemple, ils peuvent être représentés sous la forme d'un diagramme illustré à la figure 1. Principes de la POO - 2Désormais, à l'aide de l'abstraction, nous pouvons mettre en évidence des informations générales dans cette hiérarchie d'objets : un type abstrait commun d'objets - le téléphone, une caractéristique générale de le téléphone - l'année de sa création, et une interface commune - tous les téléphones sont capables de recevoir et d'envoyer des appels. Voici à quoi cela ressemble en Java :
public abstract class AbstractPhone {
    private int year;

    public AbstractPhone(int year) {
        this.year = year;
    }
    public abstract void call(int outputNumber);
    public abstract void ring (int inputNumber);
}
Sur la base de cette classe abstraite, nous pourrons créer de nouveaux types de téléphones dans le programme en utilisant d'autres principes de base de Java POO, que nous examinerons ci-dessous.

Encapsulation

A l’aide de l’abstraction, nous mettons en évidence ce qui est commun à tous les objets. Cependant, chaque modèle de téléphone est individuel et quelque peu différent des autres. Comment tracer des limites dans le programme et désigner cette individualité ? Comment pouvons-nous nous assurer qu'aucun utilisateur ne puisse accidentellement ou intentionnellement casser notre téléphone, ou essayer de convertir un modèle en un autre ? Pour le monde des objets réels, la réponse est évidente : vous devez intégrer toutes les pièces dans le corps du téléphone. Après tout, si nous ne le faisons pas et laissons à l’extérieur tous les intérieurs du téléphone et les fils qui les relient, il y aura certainement un expérimentateur curieux qui voudra « améliorer » le fonctionnement de notre téléphone. Pour éviter de telles interférences dans la conception et le fonctionnement d'un objet, la POO utilise le principe d'encapsulation - un autre principe de base de la POO, dans lequel les attributs et le comportement d'un objet sont combinés dans une seule classe, l'implémentation interne de l'objet est masquée. l'utilisateur, et une interface ouverte est fournie pour travailler avec l'objet. Le travail du programmeur consiste à déterminer quels attributs et méthodes seront accessibles au public et lesquels sont des implémentations internes de l'objet et ne doivent pas être modifiés.

Encapsulation et contrôle d'accès

Disons que lors de la production, des informations le concernant sont gravées au dos du téléphone : l’année de sa fabrication ou le logo de l’entreprise du fabricant. Cette information caractérise assez précisément ce modèle : son état. Nous pouvons dire que le développeur du téléphone a veillé à l'immuabilité de ces informations - il est peu probable que quiconque pense à supprimer la gravure. Dans le monde Java, l'état des futurs objets est décrit dans une classe à l'aide de champs, et leur comportement est décrit à l'aide de méthodes. La possibilité de changer d'état et de comportement s'effectue à l'aide de modificateurs d'accès aux champs et méthodes - private, protected, publicet default(accès par défaut). Par exemple, nous avons décidé que l'année de création, le nom du fabricant du téléphone et l'une des méthodes appartiennent à l'implémentation interne de la classe et ne peuvent pas être modifiés par d'autres objets du programme. En utilisant le code, la classe peut être décrite comme suit :
public class SomePhone {

    private int year;
    private String company;
    public SomePhone(int year, String company) {
        this.year = year;
        this.company = company;
    }
private void openConnection(){
    //findComutator
    //openNewConnection...
}
public void call() {
    openConnection();
    System.out.println("I'm calling a number");
}

public void ring() {
    System.out.println("Дзынь-дзынь");
}

 }
Un modificateur privaterend les champs et méthodes d’une classe disponibles uniquement au sein de cette classe. Cela signifie que privateles champs ne sont pas accessibles de l’extérieur et que privateles méthodes ne peuvent pas non plus être appelées. Masquer l'accès à une méthode openConnectionnous laisse également la possibilité de modifier librement l'implémentation interne de cette méthode, puisque cette méthode est garantie de ne pas être utilisée par d'autres objets et ne perturbera pas leur fonctionnement. Pour travailler avec notre objet, nous laissons les méthodes ouvertes callà l'aide ringdu modificateur public. Fournir des méthodes publiques pour travailler avec un objet fait également partie du mécanisme d'encapsulation, car si l'accès à un objet est complètement refusé, il deviendra inutile.

Héritage

Regardons à nouveau le tableau téléphonique. Vous voyez qu'il représente une hiérarchie dans laquelle le modèle situé en dessous possède toutes les caractéristiques des modèles situés plus haut sur la branche, plus les siennes. Par exemple, un smartphone utilise un réseau cellulaire pour communiquer (il possède les propriétés d'un téléphone portable), est sans fil et portable (il possède les propriétés d'un téléphone sans fil) et peut recevoir et passer des appels (il possède les propriétés d'un téléphone). Dans ce cas, on peut parler d’héritage des propriétés des objets. En programmation, l'héritage est l'utilisation de classes existantes pour en définir de nouvelles. Regardons un exemple de création d'une classe de smartphone utilisant l'héritage. Tous les téléphones sans fil sont alimentés par des piles rechargeables, qui ont une certaine durée de vie en heures. Ajoutons donc cette propriété à la classe des téléphones sans fil :
public abstract class WirelessPhone extends AbstractPhone {

    private int hour;

    public WirelessPhone(int year, int hour) {
        super(year);
        this.hour = hour;
    }
    }
callLes téléphones portables héritent des propriétés d'un téléphone sans fil, nous avons également ajouté une implémentation des méthodes et à cette classe ring:
public class CellPhone extends WirelessPhone {
    public CellPhone(int year, int hour) {
        super(year, hour);
    }

    @Override
    public void call(int outputNumber) {
        System.out.println("Calling a number" + outputNumber);
    }

    @Override
    public void ring(int inputNumber) {
        System.out.println("A subscriber is calling you" + inputNumber);
    }
}
Et enfin, la classe des smartphones qui, contrairement aux téléphones portables classiques, dispose d'un système d'exploitation à part entière. Vous pouvez ajouter de nouveaux programmes pris en charge par ce système d'exploitation sur votre smartphone, élargissant ainsi ses fonctionnalités. En utilisant le code, la classe peut être décrite comme suit :
public class Smartphone extends CellPhone {

    private String operationSystem;

    public Smartphone(int year, int hour, String operationSystem) {
        super(year, hour);
        this.operationSystem = operationSystem;
    }
public void install(String program){
    System.out.println("Installing" + program + "For" + operationSystem);
}

}
Comme vous pouvez le voir, Smartphonenous avons créé très peu de nouveau code pour décrire la classe, mais nous avons obtenu une nouvelle classe avec de nouvelles fonctionnalités. L’utilisation du principe d’héritage POO peut réduire considérablement la quantité de code, et donc faciliter le travail du programmeur.

Polymorphisme

Si nous examinons tous les modèles de téléphones, malgré les différences dans l'apparence et la conception des modèles, nous pouvons identifier un comportement commun: ils peuvent tous recevoir et passer des appels et disposer d'un ensemble de boutons de commande assez clairs et simples. En appliquant l'un des principes de base de la POO, que nous connaissons déjà, l'abstraction en termes de programmation, nous pouvons dire que l'objet téléphone a une interface commune. Ainsi, les utilisateurs de téléphones peuvent utiliser assez confortablement différents modèles en utilisant les mêmes boutons de commande (mécaniques ou tactiles), sans entrer dans les détails techniques de l'appareil. Ainsi, vous utilisez constamment un téléphone portable et vous pouvez facilement passer un appel depuis son homologue fixe. Le principe en POO selon lequel un programme peut utiliser des objets avec la même interface sans information sur la structure interne de l'objet est appelé polymorphisme . Imaginons que dans notre programme nous devions décrire un utilisateur pouvant utiliser n'importe quel modèle de téléphone pour appeler un autre utilisateur. Voici comment procéder :
public class User {
    private String name;

    public User(String name) {
        this.name = name;
            }

    public void callAnotherUser(int number, AbstractPhone phone){
// here it is polymorphism - using the abstract type AbstractPhone phone in the code!
        phone.call(number);
    }
}
 }
Décrivons maintenant les différents modèles de téléphones. Un des premiers modèles de téléphone :
public class ThomasEdisonPhone extends AbstractPhone {

public ThomasEdisonPhone(int year) {
    super(year);
}
    @Override
    public void call(int outputNumber) {
        System.out.println("Turn the Handle");
        System.out.println("Give me the phone number, sir");
    }

    @Override
    public void ring(int inputNumber) {
        System.out.println("Phone calls");
    }
}
Téléphone fixe classique :
public class Phone extends AbstractPhone {

    public Phone(int year) {
        super(year);
    }

    @Override
    public void call(int outputNumber) {
        System.out.println("I'm calling a number" + outputNumber);
    }

    @Override
    public void ring(int inputNumber) {
        System.out.println("Phone calls");
    }
}
Et enfin, un visiophone sympa :
public class VideoPhone extends AbstractPhone {

    public VideoPhone(int year) {
        super(year);
    }
    @Override
    public void call(int outputNumber) {
        System.out.println("I connect a video channel for the subscriber" + outputNumber );
    }
    @Override
    public void ring(int inputNumber) {
        System.out.println("You have an incoming video call..." + inputNumber);
    }
  }
Créons des objets dans la méthode main()et testons la méthodecallAnotherUser :
AbstractPhone firstPhone = new ThomasEdisonPhone(1879);
AbstractPhone phone = new Phone(1984);
AbstractPhone videoPhone=new VideoPhone(2018);
User user = new User("Andrey");
user.callAnotherUser(224466,firstPhone);
// Rotate the knob
// Tell me the number of the subscriber, sir
user.callAnotherUser(224466,phone);
//Call number 224466
user.callAnotherUser(224466,videoPhone);
//I connect the video channel for subscriber 224466
En appelant la même méthode sur l’objet user, nous obtenons des résultats différents. La sélection d'une implémentation de méthode spécifique callau sein d'une méthode callAnotherUsera été effectuée de manière dynamique en fonction du type spécifique de l'objet appelant lors de l'exécution du programme. C'est le principal avantage du polymorphisme : le choix de l'implémentation lors de l'exécution du programme. Dans les exemples de classes téléphoniques ci-dessus, nous avons utilisé le remplacement de méthode, une technique qui modifie l'implémentation de la méthode définie dans la classe de base sans modifier la signature de la méthode. Il s'agit essentiellement d'un remplacement de méthode, et c'est la nouvelle méthode définie dans la sous-classe qui est appelée lors de l'exécution du programme. Généralement, lors du remplacement d'une méthode, l'annotation est utilisée @Override, qui indique au compilateur de vérifier les signatures des méthodes remplacées et remplacées. De ce fait , pour vous assurer que le style de votre programme est conforme au concept de POO et aux principes de POO java, suivez ces conseils :
  • mettre en évidence les principales caractéristiques de l'objet ;
  • mettre en évidence les propriétés et les comportements communs et utiliser l'héritage lors de la création d'objets ;
  • utiliser des types abstraits pour décrire des objets ;
  • Essayez de toujours masquer les méthodes et les champs liés à l'implémentation interne de la classe.
Commentaires
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION