OOP не винайшов інкапсуляцію і не є синонімом інкапсуляції. Багато мов OOP не мають модифікаторів доступу в стилі C ++ / Java. У багатьох мовах, що не входять в ООП, доступні різні методики для пропонування капсуляції.
Класичним підходом до інкапсуляції є закриття , яке використовується у функціональному програмуванні . Це значно старше, ніж ООП, але є в чомусь еквівалентом. Наприклад, у JavaScript ми можемо створити такий об’єкт:
function Adder(x) {
this.add = function add(y) {
return x + y;
}
}
var plus2 = new Adder(2);
plus2.add(7); //=> 9
Наведений вище plus2
об'єкт не має члена, який би дозволяв прямий доступ до x
нього - він повністю інкапсульований. add()
Метод являє собою замикання по x
змінної.
Мова C підтримує деякі види інкапсуляції через механізм файлів заголовків , зокрема, непрозору техніку вказівника . В C можна оголосити назву структури без визначення її членів. На той момент жодна змінна типу цієї структури не може бути використана, але ми можемо вільно використовувати покажчики на цю структуру (оскільки розмір структурного вказівника відомий під час компіляції). Наприклад, розглянемо цей заголовок:
#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
Тепер ми можемо записувати код, який використовує цей інтерфейс Adder, не маючи доступу до його полів, наприклад:
Adder plus2 = Adder_new(2);
if (!plus2) abort();
printf("%d\n", Adder_add(plus2, 7)); /* => 9 */
Adder_free(plus2);
А ось детально вкладені деталі реалізації:
#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;
}
Існує також клас модульних мов програмування , який фокусується на інтерфейсах рівня модулів. Мовна сім'я ML в т.ч. OCaml включає цікавий підхід до модулів, званих функторами . OOP затьмарює і значною мірою поширюється на модульне програмування, але багато нібито переваги OOP більше стосуються модульності, ніж орієнтації на об'єкти.
Існує також зауваження, що класи на мовах OOP, такі як C ++ або Java, часто не використовуються для об'єктів (у розумінні об'єктів, які вирішують операції за допомогою пізнього прив'язування / динамічної диспетчеризації), а лише для абстрактних типів даних (де ми визначаємо публічний інтерфейс, який ховається внутрішні деталі реалізації). У статті " Розуміння абстрагування даних", Revisited (Cook, 2009) більш детально розглядається ця різниця.
Але так, багато мов не мають механізму інкапсуляції. Цими мовами члени структури залишаються загальнодоступними. У крайньому випадку, це буде конвенцією про іменування, яка не перешкоджає використанню. Наприклад, я думаю, що Паскаль не мав корисного механізму інкапсуляції.