OOP hat die Kapselung nicht erfunden und ist nicht gleichbedeutend mit der Kapselung. Viele OOP-Sprachen verfügen nicht über Zugriffsmodifikatoren im C ++ / Java-Stil. Viele Nicht-OOP-Sprachen verfügen über verschiedene Techniken, um die Kapselung zu ermöglichen.
Ein klassischer Ansatz für die Kapselung sind Verschlüsse , wie sie in der funktionalen Programmierung verwendet werden . Dies ist deutlich älter als OOP, aber in gewisser Weise gleichwertig. Beispielsweise können wir in JavaScript ein Objekt wie das folgende erstellen:
function Adder(x) {
this.add = function add(y) {
return x + y;
}
}
var plus2 = new Adder(2);
plus2.add(7); //=> 9
Das obige plus2
Objekt hat kein Mitglied, auf das direkt zugegriffen werden kann x
- es ist vollständig gekapselt. Die add()
Methode ist ein Abschluss über die x
Variable.
Die C- Sprache unterstützt einige Arten der Kapselung durch ihren Header- Dateimechanismus, insbesondere die opake Zeigertechnik . In C ist es möglich, einen Strukturnamen zu deklarieren, ohne seine Mitglieder zu definieren. Zu diesem Zeitpunkt kann keine Variable des Typs dieser Struktur verwendet werden, aber wir können Zeiger auf diese Struktur frei verwenden (da die Größe eines Strukturzeigers zur Kompilierungszeit bekannt ist). Betrachten Sie zum Beispiel diese Header-Datei:
#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
Wir können jetzt Code schreiben, der diese Adder-Schnittstelle verwendet, ohne Zugriff auf seine Felder zu haben, zB:
Adder plus2 = Adder_new(2);
if (!plus2) abort();
printf("%d\n", Adder_add(plus2, 7)); /* => 9 */
Adder_free(plus2);
Und hier wären die vollständig gekapselten Implementierungsdetails:
#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;
}
Es gibt auch die Klasse der modularen Programmiersprachen , die sich auf Schnittstellen auf Modulebene konzentriert. Die ML-Sprachfamilie inkl. OCaml enthält einen interessanten Ansatz für Module, die als Funktoren bezeichnet werden . OOP hat die modulare Programmierung überschattet und weitestgehend unterbewertet, doch bei vielen angeblichen Vorteilen von OOP geht es mehr um Modularität als um Objektorientierung.
Es gibt auch die Beobachtung, dass Klassen in OOP-Sprachen wie C ++ oder Java oft nicht für Objekte verwendet werden (im Sinne von Entitäten, die Operationen durch späte Bindung / dynamischen Versand auflösen), sondern nur für abstrakte Datentypen (wobei wir eine öffentliche Schnittstelle definieren, die verborgen bleibt) Details zur internen Implementierung). In dem Aufsatz Über das Verständnis der Datenabstraktion, Revisited (Cook, 2009) wird dieser Unterschied ausführlicher erörtert.
Aber ja, viele Sprachen haben überhaupt keinen Verkapselungsmechanismus. In diesen Sprachen werden Strukturmitglieder öffentlich gelassen. Allenfalls würde eine Namenskonvention von der Verwendung abhalten. Ich glaube, Pascal hatte keinen nützlichen Einkapselungsmechanismus.