Инкапсуляция (компьютерное программирование)
В программных системах инкапсуляция относится к объединению данных с механизмами или методами, которые работают с данными. Это также может относиться к ограничению прямого доступа к некоторым из этих данных, например к компонентам объекта. [1] По сути, инкапсуляция не позволяет внешнему коду заниматься внутренней работой объекта.
Инкапсуляция позволяет разработчикам представить согласованный интерфейс, независимый от его внутренней реализации. Например, инкапсуляция может использоваться для сокрытия значений или состояния объекта структурированных данных внутри класса . Это предотвращает прямой доступ клиентов к этой информации способом, который может раскрыть скрытые детали реализации или нарушить инвариантность состояния , поддерживаемую методами.
Инкапсуляция также побуждает программистов помещать весь код, связанный с определенным набором данных, в один и тот же класс, что упорядочивает его для облегчения понимания другими программистами. Инкапсуляция — это метод, который способствует развязке .
Все системы объектно-ориентированного программирования (ООП) поддерживают инкапсуляцию. [2] [3] но инкапсуляция не является уникальной особенностью ООП. Реализации абстрактных типов данных , модулей и библиотек также предлагают инкапсуляцию. Сходство было объяснено теоретиками языков программирования с точки зрения экзистенциальных типов . [4]
Значение
[ редактировать ]В объектно-ориентированных языках программирования и других смежных областях инкапсуляция относится к одному из двух связанных, но различных понятий, а иногда и к их комбинации: [5] [6]
- Языковой механизм ограничения прямого доступа к некоторым компонентам объекта . [7] [8]
- Языковая конструкция, которая облегчает объединение данных с методами (или другими функциями), работающими с этими данными. [1] [9]
Некоторые исследователи языков программирования и ученые используют первое значение отдельно или в сочетании со вторым как отличительную особенность объектно-ориентированного программирования , в то время как некоторые языки программирования, обеспечивающие лексические замыкания , рассматривают инкапсуляцию как особенность языка, ортогональную объектной ориентации.
Второе определение отражает то, что во многих объектно-ориентированных языках и других связанных областях компоненты не скрываются автоматически, и это можно переопределить. Таким образом, сокрытие информации определяется как отдельное понятие теми, кто предпочитает второе определение.
Функции инкапсуляции поддерживаются с помощью классов в большинстве объектно-ориентированных языков, хотя существуют и другие альтернативы.
Инкапсуляция и наследование
[ редактировать ]Авторы книги «Шаблоны проектирования» обсуждают противоречия между наследованием подробно и инкапсуляцией и утверждают, что, по их опыту, дизайнеры злоупотребляют наследованием. Они утверждают, что наследование часто нарушает инкапсуляцию, поскольку наследование раскрывает подклассу детали реализации его родителя. [10] Как описано в проблеме йо-йо , чрезмерное использование наследования и, следовательно, инкапсуляции может стать слишком сложным и трудным для отладки.
Скрытие информации
[ редактировать ]Согласно определению, согласно которому инкапсуляция «может использоваться для сокрытия членов данных и функций-членов», внутреннее представление объекта обычно скрыто за пределами определения объекта. Обычно только собственные методы объекта могут напрямую проверять его поля или манипулировать ими. Сокрытие внутренних компонентов объекта защищает его целостность, не позволяя пользователям переводить внутренние данные компонента в недопустимое или противоречивое состояние. Предполагаемое преимущество инкапсуляции состоит в том, что она может снизить сложность системы и, таким образом, повысить ее надежность , позволяя разработчику ограничить взаимозависимости между программными компонентами. [ нужна ссылка ]
Некоторые языки, такие как Smalltalk и Ruby, допускают доступ только через объектные методы, но большинство других (например, C++ , C# , Delphi или Java) [11] ) предлагают программисту некоторый контроль над тем, что скрыто, обычно с помощью таких ключевых слов, как public
и private
. [8] Стандарт ISO C++ относится к protected
, private
и public
как « спецификаторы доступа » и что они «не скрывают никакой информации». Сокрытие информации достигается путем предоставления скомпилированной версии исходного кода, которая подключается через файл заголовка.
Почти всегда есть способ обойти такую защиту — обычно через API отражения (Ruby, Java, C# и т. д.), иногда с помощью такого механизма, как искажение имен ( Python ), или использования специальных ключевых слов, например friend
в С++. объекта Системы, которые обеспечивают безопасность на основе возможностей (придерживаясь модели возможностей объекта ), являются исключением и гарантируют строгую инкапсуляцию.
Примеры
[ редактировать ]Ограничение полей данных
[ редактировать ]Такие языки, как C++ , C# , Java , [11] PHP , Swift и Delphi предлагают способы ограничить доступ к полям данных.
Ниже приведен пример на C# , показывающий, как можно ограничить доступ к полю данных с помощью private
ключевое слово:
class Program
{
public class Account
{
private decimal _accountBalance = 500.00m;
public decimal CheckBalance()
{
return _accountBalance;
}
}
static void Main()
{
Account myAccount = new Account();
decimal myBalance = myAccount.CheckBalance();
/* This Main method can check the balance via the public
* "CheckBalance" method provided by the "Account" class
* but it cannot manipulate the value of "accountBalance" */
}
}
Ниже приведен пример на Java :
public class Employee {
private BigDecimal salary = new BigDecimal(50000.00);
public BigDecimal getSalary() {
return this.salary;
}
public static void main() {
Employee e = new Employee();
BigDecimal sal = e.getSalary();
}
}
Инкапсуляция также возможна в необъектно-ориентированных языках. Например, в C структура может быть объявлена в общедоступном API через файл заголовка для набора функций, которые работают с элементом данных, содержащим элементы данных, которые недоступны для клиентов API с extern
ключевое слово. [12]
// Header file "api.h"
struct Entity; // Opaque structure with hidden members
// API functions that operate on 'Entity' objects
extern struct Entity * open_entity(int id);
extern int process_entity(struct Entity *info);
extern void close_entity(struct Entity *info);
// extern keywords here are redundant, but don't hurt.
// extern defines functions that can be called outside the current file, the default behavior even without the keyword
Клиенты вызывают функции API для выделения, обработки и освобождения объектов непрозрачного типа данных . Содержимое этого типа известно и доступно только реализации функций API; клиенты не могут напрямую получить доступ к его содержимому. Исходный код этих функций определяет фактическое содержимое структуры:
// Implementation file "api.c"
#include "api.h"
struct Entity {
int ent_id; // ID number
char ent_name[20]; // Name
... and other members ...
};
// API function implementations
struct Entity * open_entity(int id)
{ ... }
int process_entity(struct Entity *info)
{ ... }
void close_entity(struct Entity *info)
{ ... }
Искажение имени
[ редактировать ]Ниже приведен пример Python , который не поддерживает ограничения доступа к переменным. Однако соглашение заключается в том, что переменная, имя которой начинается с подчеркивания, должна считаться частной. [13]
class Car:
def __init__(self) -> None:
self._maxspeed = 200
def drive(self) -> None:
print(f"Maximum speed is {self._maxspeed}.")
redcar = Car()
redcar.drive() # This will print 'Maximum speed is 200.'
redcar._maxspeed = 10
redcar.drive() # This will print 'Maximum speed is 10.'
См. также
[ редактировать ]- Наследование (объектно-ориентированное программирование)
- Объектно-ориентированное программирование
- Шаблон проектирования программного обеспечения
- Фасадный рисунок
Цитаты
[ редактировать ]- ^ Jump up to: а б Роджерс, Вм. Пол (18 мая 2001 г.). «Инкапсуляция — это не сокрытие информации» . JavaWorld . Проверено 20 июля 2020 г.
- ^ «Что такое объектно-ориентированное программирование (ООП)?» . Архитектура приложения . Проверено 2 марта 2024 г.
- ^ «Инкапсуляция в объектно-ориентированном программировании (OOPS)» . www.enjoyalgorithms.com . Проверено 2 марта 2024 г.
- ^ Пирс 2002 , § 24.2 Абстракция данных с помощью экзистенциалов
- ^ Скотт, Майкл Ли (2006). Прагматика языка программирования (2-е изд.). Морган Кауфманн. п. 481. ИСБН 978-0-12-633951-2 .
Механизмы инкапсуляции позволяют программисту группировать данные и подпрограммы, которые с ними работают, в одном месте и скрывать ненужные детали от пользователей абстракции.
- ^ Дейл, Нелл Б.; Уимс, Чип (2007). Программирование и решение проблем с помощью Java (2-е изд.). Джонс и Бартлетт. п. 396. ИСБН 978-0-7637-3402-2 .
- ^ Митчелл, Джон К. (2003). Концепции в языках программирования . Издательство Кембриджского университета. п. 522. ИСБН 978-0-521-78098-8 .
- ^ Jump up to: а б Пирс, Бенджамин (2002). Типы и языки программирования . МТИ Пресс. п. 266. ИСБН 978-0-262-16209-8 .
- ^ Коннолли, Томас М.; Бегг, Кэролайн Э. (2005). «Глава 25: Введение в объектную DMBS § Объектно-ориентированные концепции». Системы баз данных: практический подход к проектированию, внедрению и управлению (4-е изд.). Пирсон Образование. п. 814. ИСБН 978-0-321-21025-8 .
- ^ Гамма, Эрих; Хелм, Ричард; Джонсон, Ральф; Влиссидес, Джон (1994). Шаблоны проектирования . Аддисон-Уэсли. ISBN 978-0-201-63361-0 .
- ^ Jump up to: а б Bloch 2018 , стр. 73–77, глава §4, пункт 15. Минимизируйте доступность классов и членов.
- ^ Кинг, КН (2008). Программирование на C: современный подход (2-е изд.). WW Нортон и компания. п. 464. ИСБН 978-0393979503 .
- ^ Бадер, Дэн. «Значение подчеркиваний в Python» . Улучшите свои навыки Python . Проверено 1 ноября 2019 г.
Ссылки
[ редактировать ]- Блох, Джошуа (2018). «Эффективная Java: Руководство по языку программирования» (третье изд.). Аддисон-Уэсли. ISBN 978-0134685991 .