Инкапсуляция (компьютерное программирование) - Encapsulation (computer programming)

В объектно-ориентированного программирования (ООП), инкапсуляция относится к объединению данных с методами, которые работают с этими данными, или к ограничению прямого доступа к некоторым компонентам объекта.[1] Инкапсуляция используется для скрытия значений или состояния объекта структурированных данных внутри объекта. учебный класс, предотвращая прямой доступ к ним посторонних лиц. Общедоступные методы обычно предоставляются в классе (так называемые "геттеры" и "сеттеры" ) для доступа к значениям, а другие клиентские классы вызывают эти методы для получения и изменения значений в объекте.

Этот механизм не является уникальным для ООП. Реализации абстрактные типы данных, например, модули, предлагают аналогичную форму инкапсуляции. Сходство было объяснено теоретиками языков программирования с точки зрения экзистенциальные типы.[2]

Смысл

В объектно-ориентированные языки программирования, и других связанных полей, инкапсуляция относится к одному из двух связанных, но различных понятий, а иногда и к их комбинации:[3][4]

  • Языковой механизм для ограничения прямого доступа к некоторым из объект компоненты.[5][6]
  • Конструкция языка, которая облегчает объединение данных с методы (или другие функции), работающие с этими данными.[1][7]

Некоторые исследователи языков программирования и ученые используют первое значение отдельно или в сочетании со вторым в качестве отличительной особенности объектно-ориентированного программирования, в то время как некоторые языки программирования, которые предоставляют лексические замыкания рассматривать инкапсуляцию как особенность языка ортогональный объектной ориентации.

Второе определение мотивировано тем фактом, что во многих объектно-ориентированных языках и других связанных областях компоненты не скрываются автоматически, и это можно переопределить; таким образом, скрытие информации определяется как отдельное понятие теми, кто предпочитает второе определение.

Возможности инкапсуляции поддерживаются с помощью классы в большинстве объектно-ориентированных языков, хотя существуют и другие альтернативы.

Инкапсуляция и наследование

Авторы Шаблоны проектирования обсудить напряжение между наследование и инкапсуляция подробно и утверждает, что, по их опыту, дизайнеры злоупотребляют наследованием. Они утверждают, что наследование часто нарушает инкапсуляцию, учитывая, что наследование предоставляет подклассу сведения о его родительской реализации.[8] Как описано в йо-йо проблема, чрезмерное использование наследования и, следовательно, инкапсуляции, может стать слишком сложным и трудным для отладки.

Скрытие информации

Согласно определению, что инкапсуляция «может использоваться для сокрытия элементов данных и функций-членов», внутреннее представление объект обычно скрыт от глаз за пределами определения объекта. Обычно только собственные методы объекта могут напрямую проверять его поля или управлять ими. Скрытие внутренних компонентов объекта защищает его целостность, не позволяя пользователям переводить внутренние данные компонента в недопустимое или несогласованное состояние. Предполагаемое преимущество инкапсуляции состоит в том, что она может снизить сложность системы и, следовательно, увеличить надежность, позволяя разработчику ограничивать взаимозависимости между программными компонентами.[нужна цитата ]

Некоторые языки, такие как Болтовня и Рубин разрешить доступ только через методы объекта, но большинство других (например, C ++, C #, Delphi или же Ява ) предлагают программисту степень контроля над тем, что скрыто, обычно с помощью таких ключевых слов, как общественный и частный.[6] Стандарт ISO C ++ относится к защищенный, частный и общественный в качестве "спецификаторы доступа "и что они не" скрывают никакой информации ". Сокрытие информации достигается путем предоставления скомпилированной версии исходного кода, которая сопоставляется через файл заголовка.

Почти всегда есть способ обойти такую ​​защиту - обычно через отражение API (Ruby, Java, C # и т. Д.), Иногда с помощью такого механизма, как искажение имени (Python ) или использование специального ключевого слова, например друг в C ++.

Примеры

Ограничение полей данных

Такие языки, как C ++, C #, Ява, PHP, Быстрый, и Delphi предлагать способы ограничения доступа к полям данных.

Ниже приведен пример в C # который показывает, как можно ограничить доступ к полю данных с помощью частный ключевое слово:

учебный класс Программа{    общественный учебный класс Счет    {        частный десятичный остаток на счету = 500.00м;        общественный десятичный Проверить баланс()        {            возвращаться это.остаток на счету;        }    }    статический пустота Главный()    {        Счет мой счет = новый Счет();        десятичный myBalance = мой счет.Проверить баланс();        / * Этот метод Main может проверять баланс через публичный         * Метод "CheckBalance", предоставляемый классом "Account"          * но он не может управлять значением accountBalance * /    }}

Ниже приведен пример в Ява:

общественный учебный класс Наемный рабочий {    частный BigDecimal зарплата = новый BigDecimal(50000.00);        общественный BigDecimal getSalary() {        возвращаться это.зарплата;    }    общественный статический пустота главный() {        Наемный рабочий е = новый Наемный рабочий();        BigDecimal сал = е.getSalary();    }}

Инкапсуляция также возможна в не объектно-ориентированных языках. В C, например, структура может быть объявлена ​​в общедоступном API через файл заголовка для набора функций, которые работают с элементом данных, содержащим элементы данных, которые недоступны для клиентов API с внешний ключевое слово.[9][10]

// Заголовочный файл "api.h"структура Юридическое лицо;          // Непрозрачная структура со скрытыми членами// Функции API, которые работают с объектами Entityвнешний структура Юридическое лицо *  open_entity(int я бы);внешний int              process_entity(структура Юридическое лицо *Информация);внешний пустота             close_entity(структура Юридическое лицо *Информация);// Ключевые слова extern здесь избыточны, но не повредят.// extern определяет функции, которые могут быть вызваны вне текущего файла, поведение по умолчанию даже без ключевого слова

Клиенты вызывают функции API для выделения, работы и освобождения объектов непрозрачный тип данных. Содержимое этого типа известно и доступно только для реализации функций API; клиенты не могут напрямую получить доступ к его содержимому. Исходный код этих функций определяет фактическое содержимое структуры:

// Файл реализации "api.c"#включают "api.h"структура Юридическое лицо {    int     ent_id;         // Идентификационный номер    char    ent_name[20];   // Имя    ... и Другой члены ...};// Реализации функций APIструктура Юридическое лицо * open_entity(int я бы){ ... }int process_entity(структура Юридическое лицо *Информация){ ... }пустота close_entity(структура Юридическое лицо *Информация){ ... }

Изменение имени

Ниже приведен пример Python, который не поддерживает ограничения доступа к переменным. Однако существует соглашение, что переменная, имя которой начинается с символа подчеркивания, должна считаться частной.[11]

учебный класс Машина:     def __в этом__(себя) -> Никто:        себя._максимальная скорость = 200     def водить машину(себя) -> Никто:        Распечатать(ж"Максимальная скорость {self._maxspeed}.") Красная машина = Машина()Красная машина.водить машину()  # Будет напечатано "Максимальная скорость 200."Красная машина._максимальная скорость = 10Красная машина.водить машину()  # Будет напечатано "Максимальная скорость 10".

Смотрите также

Рекомендации

  1. ^ а б Роджерс, Вм. Пол (18 мая 2001 г.). «Инкапсуляция - это не сокрытие информации». JavaWorld. Получено 2020-07-20.
  2. ^ Пирс 2002, § 24.2 Абстракция данных с помощью экзистенциалов
  3. ^ Скотт, Майкл Ли (2006). Прагматика языка программирования (2-е изд.). Морган Кауфманн. п. 481. ISBN  978-0-12-633951-2. Механизмы инкапсуляции позволяют программисту группировать данные и подпрограммы, которые с ними работают, вместе в одном месте и скрывать нерелевантные детали от пользователей абстракции.
  4. ^ Дейл, Нелл Б.; Уимс, Чип (2007). Программирование и решение проблем с Java (2-е изд.). Джонс и Бартлетт. п. 396. ISBN  978-0-7637-3402-2.
  5. ^ Митчелл, Джон С. (2003). Понятия в языках программирования. Издательство Кембриджского университета. п. 522. ISBN  978-0-521-78098-8.
  6. ^ а б Пирс, Бенджамин (2002). Типы и языки программирования. MIT Press. п. 266. ISBN  978-0-262-16209-8.CS1 maint: ref = harv (связь)
  7. ^ Коннолли, Томас М .; Бегг, Кэролайн Э. (2005). «Глава 25: Введение в объектную DMBS § Объектно-ориентированные концепции». Системы баз данных: практический подход к проектированию, внедрению и управлению (4-е изд.). Pearson Education. п. 814. ISBN  978-0-321-21025-8.
  8. ^ Гамма, Эрих; Хелм, Ричард; Джонсон, Ральф; Влиссидес, Джон (1994). Шаблоны проектирования. Эддисон-Уэсли. ISBN  978-0-201-63361-0.
  9. ^ Кинг, К. Н. (2008). Программирование на C: современный подход (PDF) (2-е изд.). W. W. Norton & Company. п. 464. ISBN  978-0393979503. Получено 1 ноября 2019.
  10. ^ Кинг, Ким Н. Программирование на C: современный подход. WW Norton & Company, 2008. Гл. 18, стр. 464, г. ISBN  0393979504
  11. ^ Бадер, Дэн. «Значение подчеркивания в Python». Улучшите свои навыки Python. Получено 1 ноября 2019.