OOP n'a pas inventé l'encapsulation et n'est pas synonyme d'encapsulation. De nombreux langages POO n'ont pas de modificateurs d'accès de style C ++ / Java. De nombreuses langues non-POO disposent de diverses techniques pour offrir une encapsulation.
Une approche classique de l’encapsulation est la fermeture , utilisée dans la programmation fonctionnelle . C'est beaucoup plus vieux que la POO mais est en quelque sorte équivalent. Par exemple, en JavaScript, nous pourrions créer un objet comme ceci:
function Adder(x) {
this.add = function add(y) {
return x + y;
}
}
var plus2 = new Adder(2);
plus2.add(7); //=> 9
L' plus2
objet ci-dessus n'a aucun membre qui permettrait un accès direct à x
- il est entièrement encapsulé. La add()
méthode est une fermeture sur la x
variable.
Le langage C prend en charge certains types d'encapsulation via son mécanisme de fichier d'en-tête , notamment la technique du pointeur opaque . En C, il est possible de déclarer un nom de structure sans définir ses membres. À ce stade, aucune variable du type de cette structure ne peut être utilisée, mais nous pouvons utiliser librement les pointeurs sur cette structure (car la taille d'un pointeur de structure est connue au moment de la compilation). Par exemple, considérons ce fichier d’en-tête:
#ifndef ADDER_H
#define ADDER_H
typedef struct AdderImpl *Adder;
Adder Adder_new(int x);
void Adder_free(Adder self);
int Adder_add(Adder self, int y);
#endif
Nous pouvons maintenant écrire du code qui utilise cette interface Adder, sans avoir accès à ses champs, par exemple:
Adder plus2 = Adder_new(2);
if (!plus2) abort();
printf("%d\n", Adder_add(plus2, 7)); /* => 9 */
Adder_free(plus2);
Et voici les détails de la mise en œuvre totalement encapsulée:
#include "adder.h"
struct AdderImpl { int x; };
Adder Adder_new(int x) {
Adder self = malloc(sizeof *self);
if (!self) return NULL;
self->x = x;
return self;
}
void Adder_free(Adder self) {
free(self);
}
int Adder_add(Adder self, int y) {
return self->x + y;
}
Il existe également la classe des langages de programmation modulaires , qui se concentre sur les interfaces au niveau des modules. La famille de langues ML incl. OCaml inclut une approche intéressante des modules appelés foncteurs . La programmation modulaire occultée et en grande partie occultée par la programmation orientée objet, mais de nombreux avantages supposés de la programmation orientée objet concernent davantage la modularité que l'orientation objet.
Il y a aussi l'observation que les classes dans les langages POO tels que C ++ ou Java ne sont souvent pas utilisées pour les objets (dans le sens d'entités qui résolvent des opérations par liaison / dispatch dynamique tardive) mais simplement pour les types de données abstraits (où nous définissons une interface publique qui cache détails de la mise en œuvre interne). Le document intitulé Comprendre l'abstraction des données, revisité (Cook, 2009) examine cette différence plus en détail.
Mais oui, beaucoup de langues n’ont aucun mécanisme d’encapsulation. Dans ces langues, les membres de la structure sont laissés publics. Tout au plus, il y aurait une convention de nommage décourageant l'utilisation. Par exemple, je pense que Pascal n'avait pas de mécanisme d'encapsulation utile.