web-dev-qa-db-fra.com

Abstraction vs Encapsulation dans Java

Duplicate possible:
Abstraction VS Information Cacher VS Encapsulation

Je sais que cette question a peut-être été posée des milliers de fois sur ce forum, même si net contient également de nombreuses définitions de ces concepts, mais que tous ont la même apparence et utilisent tous les mêmes mots techniques. Par exemple les définitions suivantes

L'encapsulation est un processus permettant de lier ou d'encapsuler les données et les codes agissant sur les données en une seule entité. Cela protège les données de l’interface extérieure et de leur mauvaise utilisation. Une façon de penser à l'encapsulation consiste à utiliser un wrapper protecteur qui empêche l'accès arbitraire au code et aux données par un autre code défini en dehors du wrapper.

Ce que j’ai compris de la définition ci-dessus, c’est que créer des variables, les marquer comme privées et générer un getter-setter pour ces variables et utiliser object pour accéder à ces getter et setter. De cette manière, les données sont cachées à l'intérieur de l'objet et ne sont accessibles que par l'objet. J'espère que j'ai raison .


L'abstraction est le processus décrit dans Java qui sert à masquer certains détails et à ne montrer que les fonctionnalités essentielles de l'objet. En d'autres termes, il s'agit de la vue extérieure d'un objet (interface).

Maintenant, c'est la partie qui me confond toujours. Chaque fois que je pense à l'abstraction, la chose qui me vient à l'esprit est la classe abstraite (peut-être parce que les deux ont un mot-clé abstrait). Au-dessus de la définition, l’abstraction signifie masquer des données et ne montrer que les détails requis, mais c’est ce que nous faisons déjà dans le droit d’encapsulation? alors quelle est la différence. Aussi je n'ai pas eu ce qui est vue de côté d'objet en il s'agit de la vue de l'extérieur d'un objet .

Quelqu'un peut-il s'il vous plaît mettre plus de lumière sur cela avec des exemples réels ou avec des exemples de programmation si possible.

84
Sandeep Kumar

Abstraction de OO lors de la conception au niveau de la classe, avec l'objectif de masquer la complexité d'implémentation de comment les fonctionnalités offertes par un API/design/système ont été implémentées, ce qui simplifie en quelque sorte l'interface d'accès l'implémentation sous-jacente.

Le processus d'abstraction peut être répété à des niveaux (couches) de classes de plus en plus "élevés", ce qui permet de construire de grands systèmes sans augmenter la complexité du code et la compréhension de chaque couche.

Par exemple, un développeur Java peut utiliser les fonctionnalités de haut niveau de FileInputStream sans se soucier de la façon dont cela fonctionne (c.-à-d. Descripteurs de fichier, contrôles de sécurité du système de fichiers, allocation de mémoire et la mise en mémoire tampon sera gérée en interne et est cachée des consommateurs). Cela permet de modifier l'implémentation de FileInputStream et tant que l'API (interface) de FileInputStream reste cohérente, le code créé par rapport aux versions précédentes continuera à fonctionner.

De même, lors de la conception de vos propres classes, vous souhaiterez masquer autant que possible les détails de la mise en œuvre interne.

Dans la définition de Booch1, OO L'encapsulation est réalisée par masquage d'informations , et plus particulièrement autour du masquage de données internes (champs/membres représentant l’État) appartenant à une instance de classe, en imposant un accès contrôlé aux données internes, en empêchant toute modification externe directe de ces champs, ainsi qu’en masquant toute implémentation interne méthodes de la classe (par exemple en les rendant privées).

Par exemple, les champs d'une classe peuvent être définis par défaut sur private, et uniquement si un accès externe à ceux-ci est requis, une get() et/ou set() (ou Property) seront exposés à partir de la classe. (De nos jours, OO] _ langues, les champs peuvent être marqués comme suit: readonly/final/immutable, ce qui restreint encore plus les modifications, même au sein de la classe.

Exemple où NO masquage d'information a été appliqué (mauvaise pratique) :

class Foo {
   // BAD - NOT Encapsulated - code external to the class can change this field directly
   // Class Foo has no control over the range of values which could be set.
   public int notEncapsulated;
}

Exemple d'application de l'encapsulation de champ :

class Bar {
   // Improvement - access restricted only to this class
   private int encapsulatedPercentageField;

   // The state of Bar (and its fields) can now be changed in a controlled manner
   public void setEncapsulatedField(int percentageValue) {
      if (percentageValue >= 0 && percentageValue <= 100) {
          encapsulatedPercentageField = percentageValue;
      }
      // else throw ... out of range
   }
}

Exemple d'initialisation immuable/constructeur uniquement d'un champ :

class Baz {
   private final int immutableField;

   public void Baz(int onlyValue) {
      // ... As above, can also check that onlyValue is valid
      immutableField = onlyValue;
   }
   // Further change of `immutableField` outside of the constructor is NOT permitted, even within the same class 
}

Re: Abstraction vs Abstract Class

Les classes abstraites sont des classes qui encouragent la réutilisation des éléments communs entre les classes, mais qui ne peuvent elles-mêmes être instanciées directement avec new(). Les classes abstraites doivent être sous-classées et seules les sous-classes concrete (non abstraite) peut être instancié. L'une des sources de confusion entre Abstraction et un abstract class est que, dans les premiers jours de OO, l'héritage était davantage utilisé pour obtenir une réutilisation du code (par exemple, avec des classes de base abstraites associées). De nos jours, la composition est généralement privilégiée par rapport à l'héritage , et il existe davantage d'outils disponibles pour réaliser des abstractions, tels que les interfaces, les événements/délégués/fonctions, les traits/mixines, etc.

Objet: Encapsulation ou masquage d'informations

La signification de encapsulation semble avoir évolué avec le temps et récemment encapsulation peut généralement aussi être utilisé dans un sens plus général pour déterminer les méthodes, champs, propriétés, événements, etc. à regrouper dans une classe .

Citant Wikipedia:

Dans le cadre plus concret d'un langage de programmation orienté objet, la notion est utilisée pour désigner soit un mécanisme de masquage d'informations, soit un mécanisme de regroupement, soit la combinaison des deux.

Par exemple, dans la déclaration

J'ai encapsulé le code d'accès aux données dans sa propre classe

.. L’interprétation de encapsulation est à peu près équivalente à la séparation des problèmes ou au principal à responsabilité unique (le "S" dans SOLID), et pourrait sans doute être utilisé comme synonyme de refactoring.


[1] Une fois que vous avez vu la photo du chat d'encapsulation de Booch , vous ne pourrez plus jamais oublier l'encapsulation - p.41 de l'analyse orientée objet et de la conception avec applications, 2e édition

83
StuartLC

En termes simples: vous faites abstraction lorsque vous décidez quoi mettre en œuvre. Vous effectuez une encapsulation lorsque vous cachez quelque chose que vous avez implémenté.

49
mbm

L'abstraction concerne identifie les points communs et réduit les fonctionnalités avec lesquelles vous devez travailler à différents niveaux de votre code.

par exemple. Je peux avoir une classe Vehicle. Car dériverait de Vehicle, de même que Motorbike. Je peux demander à chaque Vehicle le nombre de roues, de passagers, etc., et ces informations ont été extraites et identifiées comme communes à partir de Cars et Motorbikes.

Dans mon code, je peux souvent gérer Vehicles via des méthodes courantes go(), stop() etc. Lorsque j'ajoute un nouveau type de véhicule plus tard (par exemple, Scooter), la majorité de mon code reste inconscient de ce fait, et la mise en œuvre de Scooter s'inquiète uniquement des particularités de Scooter.

33
Brian Agnew