CodeGym/Blog Java/Random-FR/Principes de la POO
Auteur
Milan Vucic
Programming Tutor at Codementor.io

Principes de la POO

Publié dans le groupe Random-FR
membres
Java est un langage orienté objet. Cela signifie que vous devez écrire des programmes Java en utilisant un paradigme orienté objet. Et ce paradigme implique l'utilisation d'objets et de classes dans vos programmes. Essayons d'utiliser des exemples pour comprendre ce que sont les classes et les objets, et comment appliquer les principes de base de la POO (abstraction, héritage, polymorphisme et encapsulation) dans la pratique.

Qu'est-ce qu'un objet ?

Le monde dans lequel nous vivons est composé d'objets. En regardant autour de nous, nous pouvons voir que nous sommes entourés de maisons, d'arbres, de voitures, de meubles, de vaisselle et d'ordinateurs. Toutes ces choses sont des objets, et chacune d'elles a un ensemble de caractéristiques, de comportements et d'objectifs spécifiques. Nous sommes habitués aux objets, et nous les utilisons toujours à des fins bien précises. Par exemple, si nous devons nous rendre au travail, nous utilisons une voiture. Si nous voulons manger, nous utilisons des plats. Et si nous voulons nous reposer, nous trouvons un canapé confortable. Les humains sont habitués à penser en termes d'objets pour résoudre les problèmes de la vie quotidienne. C'est une des raisons pour lesquelles les objets sont utilisés en programmation. Cette approche est appelée programmation orientée objet. Donnons un exemple. Imaginez que vous ayez développé un nouveau téléphone et que vous souhaitiez lancer une production de masse. En tant que développeur du téléphone, vous savez à quoi il sert, comment il fonctionne et quelles sont ses parties (corps, microphone, haut-parleur, fils, boutons, etc.). De plus, vous seul savez comment connecter ces pièces. Mais vous n'avez pas l'intention de fabriquer les téléphones personnellement — vous avez toute une équipe de travailleurs pour le faire. Pour éliminer le besoin d'expliquer à plusieurs reprises comment connecter les pièces du téléphone et pour vous assurer que tous les téléphones sont fabriqués de la même manière, avant de commencer à les produire, vous devez créer un dessin décrivant l'organisation du téléphone. En POO, nous appelons une telle description, dessin, diagramme ou modèle une classe. Il constitue la base de la création d'objets lorsque le programme est en cours d'exécution. Une classe est une description d'objets d'un certain type, comme un modèle commun composé de champs, de méthodes et d'un constructeur. Un objet est une instance d'une classe.

Abstraction

Réfléchissons maintenant à la façon dont nous pouvons passer d'un objet dans le monde réel à un objet dans un programme. Nous utiliserons le téléphone comme exemple. Ce moyen de communication a une histoire qui s'étend sur plus de 100 ans. Le téléphone moderne est un appareil beaucoup plus complexe que son prédécesseur du XIXe siècle. Lorsque nous utilisons le téléphone, nous ne pensons pas à son organisation et aux processus qui s'y déroulent. On utilise simplement les fonctions fournies par les développeurs du téléphone : des boutons ou un écran tactile pour entrer un numéro de téléphone et passer des appels. L'une des premières interfaces téléphoniques était une manivelle qui devait être tournée pour passer un appel. Bien sûr, ce n'était pas très pratique. Mais il remplissait parfaitement sa fonction. Si vous comparez les téléphones les plus modernes et les tout premiers, vous pouvez immédiatement identifier les fonctions les plus importantes pour l'appareil de la fin du XIXe siècle et pour le smartphone moderne. Ils sont la capacité de passer des appels et la capacité de recevoir des appels. En fait, c'est ce qui fait du téléphone un téléphone, et pas autre chose. Je viens maintenant d'appliquer un principe de POO : identifier les caractéristiques et les informations les plus importantes d'un objet. Ce principe s'appelle l'abstraction. En POO, l'abstraction peut également être définie comme une méthode de représentation des éléments d'une tâche du monde réel en tant qu'objets dans un programme. L'abstraction est toujours associée à la généralisation de certaines propriétés d'un objet, donc l'essentiel est de séparer les informations significatives de l'insignifiant dans le contexte de la tâche à accomplir. De plus, il peut y avoir plusieurs niveaux d'abstraction. Laisser' s essayer d'appliquer le principe d'abstraction à nos téléphones. Pour commencer, nous allons identifier les types de téléphones les plus courants, des tout premiers téléphones à ceux d'aujourd'hui. Par exemple, nous pourrions les représenter sous la forme du schéma de la figure 1. Principes de la POO - 2Grâce à l'abstraction, nous pouvons maintenant identifier les informations générales dans cette hiérarchie d'objets : l'objet abstrait général (téléphone), les caractéristiques communes du téléphone (par exemple, l'année de sa création) et l'interface commune (tous les téléphones peuvent recevoir et émettre 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 outgoingNumber);
    public abstract void ring(int incomingNumber);
}
Dans un programme, nous pouvons créer de nouveaux types de téléphones en utilisant cette classe abstraite et en appliquant d'autres principes de base de la POO, que nous explorerons ci-dessous.

Encapsulation

Avec l'abstraction, nous identifions ce qui est commun à tous les objets. Mais chaque type de téléphone est unique et diffère en quelque sorte des autres. Dans un programme, comment trace-t-on des frontières et identifie-t-on cette individualité ? Comment faire en sorte que personne ne puisse accidentellement ou délibérément casser notre téléphone ou essayer de convertir un modèle en un autre ? Dans le monde réel, la réponse est évidente : vous devez mettre toutes les pièces dans une coque de téléphone. Après tout, si vous ne le faites pas - en laissant à la place toutes les pièces internes du téléphone et les fils de connexion à l'extérieur - un expérimentateur curieux voudra certainement "améliorer" notre téléphone. Pour éviter de tels bricolages, le principe d'encapsulation est utilisé dans la conception et le fonctionnement d'un objet. Ce principe stipule que les attributs et le comportement d'un objet sont combinés dans une seule classe, l'objet' L'implémentation interne de s est cachée à l'utilisateur et une interface publique est fournie pour travailler avec l'objet. La tâche du programmeur est de déterminer lesquels des attributs et des méthodes d'un objet doivent être accessibles au public, et quels sont les détails d'implémentation internes qui doivent être inaccessibles.

Encapsulation et contrôle d'accès

Supposons que des informations sur un téléphone (son année de production ou le logo du fabricant) soient gravées sur son dos lors de sa fabrication. L'information (son état) est spécifique à ce modèle particulier. On peut dire que le fabricant s'est assuré que cette information était immuable — il est peu probable que quelqu'un pense à retirer la gravure. Dans le monde Java, une classe décrit l'état des objets futurs à l'aide de champs, et leur comportement est décrit à l'aide de méthodes. L'accès à l'état et au comportement d'un objet est contrôlé à l'aide de modificateurs appliqués aux champs et aux méthodes : privé, protégé, public et par défaut. Par exemple, nous avons décidé que l'année de production, le nom du fabricant et l'une des méthodes sont des détails d'implémentation internes de la classe et ne peuvent pas être modifiés par d'autres objets du programme. Dans du code,
public class SomePhone {

    private int year;
    private String company;
    public SomePhone(int year, String company) {
        this.year = year;
        this.company = company;
    }
private void openConnection(){
    // findSwitch
    // openNewConnection...
}
public void call() {
    openConnection();
    System.out.println("Calling");
}

public void ring() {
    System.out.println("Ring-ring");
}

 }
Le modificateur privé permet d'accéder aux champs et aux méthodes de la classe uniquement dans cette classe. Cela signifie qu'il est impossible d'accéder aux champs privés de l'extérieur, car les méthodes privées ne peuvent pas être appelées. Restreindre l'accès à la méthode openConnection nous laisse également la possibilité de modifier librement l'implémentation interne de la méthode, car la méthode est garantie de ne pas être utilisée par ou d'interrompre le travail d'autres objets. Pour travailler avec notre objet, nous laissons les méthodes call et ring disponibles en utilisant le modificateur public. Fournir des méthodes publiques pour travailler avec des objets fait également partie de l'encapsulation, car si l'accès était complètement refusé, il deviendrait inutile.

Héritage

Jetons un autre regard sur le schéma des téléphones. Vous pouvez voir qu'il s'agit d'une hiérarchie dans laquelle un modèle possède toutes les caractéristiques des modèles situés plus haut le long de sa branche, et ajoute certaines des siennes. Par exemple, un smartphone utilise un réseau cellulaire pour la communication (a les propriétés d'un téléphone portable), est sans fil et portable (a les propriétés d'un téléphone sans fil) et peut recevoir et passer des appels (a les propriétés d'un téléphone). Ce que nous avons ici est l'héritage des propriétés de l'objet. En programmation, l'héritage consiste à utiliser des classes existantes pour en définir de nouvelles. Prenons un exemple d'utilisation de l'héritage pour créer une classe smartphone. Tous les téléphones sans fil sont alimentés par des batteries rechargeables, qui ont une certaine autonomie. En conséquence, nous ajoutons cette propriété à la classe des téléphones sans fil :
public abstract class CordlessPhone extends AbstractPhone {

    private int hour;

    public CordlessPhone (int year, int hour) {
        super(year);
        this.hour = hour;
    }
    }
Les téléphones portables héritent des propriétés d'un téléphone sans fil, et nous implémentons les méthodes d'appel et de sonnerie dans cette classe :
public class CellPhone extends CordlessPhone {
    public CellPhone(int year, int hour) {
        super(year, hour);
    }

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

    @Override
    public void ring(int incomingNumber) {
        System.out.println("Incoming call from " + incomingNumber);
    }
}
Et enfin, nous avons la classe des smartphones, qui, contrairement aux téléphones portables classiques, dispose d'un système d'exploitation à part entière. Vous pouvez étendre les fonctionnalités de votre smartphone en ajoutant de nouveaux programmes pouvant s'exécuter sur son système d'exploitation. Dans 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, nous avons créé pas mal de nouveau code pour décrire la classe Smartphone , mais nous avons une nouvelle classe avec de nouvelles fonctionnalités. Ce principe de la POO permet de réduire significativement la quantité de code Java nécessaire, facilitant ainsi la vie du programmeur.

Polymorphisme

Malgré les différences d'apparence et de conception des différents types de téléphones, nous pouvons identifier certains comportements communs : ils peuvent tous recevoir et passer des appels et tous ont un ensemble de commandes assez clair et simple. En termes de programmation, le principe d'abstraction (que nous connaissons déjà) permet de dire que les objets téléphone ont une interface commune. C'est pourquoi les gens peuvent facilement utiliser différents modèles de téléphones qui ont les mêmes commandes (boutons mécaniques ou écran tactile), sans se plonger 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 la ligne fixe de votre ami. Le principe de la POO qui dit qu'un programme peut utiliser des objets avec une interface commune sans aucune information sur la structure interne de l'objet est appelé polymorphisme. Laisser' imaginons que nous ayons besoin de notre programme pour décrire un utilisateur qui peut utiliser n'importe quel téléphone pour appeler un autre utilisateur. Voici comment nous pouvons le faire :
public class User {
    private String name;

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

    public void callAnotherUser(int number, AbstractPhone phone){
// And here's polymorphism: using the AbstractPhone type in the code!
        phone.call(number);
    }
}
 }
Nous allons maintenant décrire plusieurs types de téléphones. Un des premiers téléphones :
public class ThomasEdisonPhone extends AbstractPhone {

public ThomasEdisonPhone(int year) {
    super(year);
}
    @Override
    public void call(int outgoingNumber) {
        System.out.println("Crank the handle");
        System.out.println("What number would you like to connect to?");
    }

    @Override
    public void ring(int incomingNumber) {
        System.out.println("The phone is ringing");
    }
}
Un téléphone fixe ordinaire :
public class Phone extends AbstractPhone {

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

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

    @Override
    public void ring(int incomingNumber) {
        System.out.println("The phone is ringing");
    }
}
Et enfin, un visiophone sympa:
public class VideoPhone extends AbstractPhone {

    public VideoPhone(int year) {
        super(year);
    }
    @Override
    public void call(int outgoingNumber) {
        System.out.println("Connecting video call to " + outgoingNumber);
    }
    @Override
    public void ring(int incomingNumber) {
        System.out.println("Incoming video call from " + incomingNumber);
    }
  }
Nous allons créer des objets dans la méthode main() et tester la méthode callAnotherUser() :
AbstractPhone firstPhone = new ThomasEdisonPhone(1879);
AbstractPhone phone = new Phone(1984);
AbstractPhone videoPhone=new VideoPhone(2018);
User user = new User("Jason");
user.callAnotherUser(224466, firstPhone);
// Crank the handle
// What number would you like to connect to?
user.callAnotherUser(224466, phone);
// Calling 224466
user.callAnotherUser(224466, videoPhone);
// Connecting video call to 224466
L'appel de la même méthode sur l' objet utilisateur produit des résultats différents. Une implémentation spécifique de la méthode d'appel est sélectionnée dynamiquement dans la méthode callAnotherUser() en fonction du type spécifique d'objet passé lors de l'exécution du programme. C'est le principal avantage du polymorphisme - la possibilité de choisir une implémentation au moment de l'exécution. Dans les exemples de classes de téléphone donnés ci-dessus, nous avons utilisé le remplacement de méthode - une astuce dans laquelle nous modifions l'implémentation d'une méthode définie dans la classe de base sans modifier la signature de la méthode. Cela remplace essentiellement la méthode : la nouvelle méthode définie dans la sous-classe est appelée lorsque le programme est exécuté. Habituellement, lorsque nous redéfinissons une méthode, le @Overridel'annotation est utilisée. Il indique au compilateur de vérifier les signatures des méthodes surchargées et surchargées. Enfin, pour vous assurer que vos programmes Java sont cohérents avec les principes de la POO, suivez ces conseils :
  • identifier les principales caractéristiques d'un objet ;
  • identifier les propriétés et comportements communs et utiliser l'héritage lors de la création de classes ;
  • 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 d'une classe.
Commentaires
  • Populaires
  • Nouveau
  • Anciennes
Tu dois être connecté(e) pour laisser un commentaire
Cette page ne comporte pas encore de commentaires