Диаграмма объекта и его взаимодействия через методы, а не непосредственно с данными

Инкапсуляция (англ. encapsulation, от лат. in capsula) — в информатике, размещение в одном компоненте данных и методов, которые с ними работают. В реализации большинства языков программирования (C++, C#, Java и другие) обеспечивается механизм сокрытия, позволяющий разграничивать доступ к различным частям компонента.

Инкапсуляция зачастую рассматривается как понятие, присущее исключительно объектно-ориентированному программированию (ООП), но в действительности обширно встречается и в других (см. подтипизация на записях и полиморфизм записей и вариантов). В ООП инкапсуляция тесно связана с принципом абстракции данных (не путать с абстрактными типами данных, реализации которых предоставляют возможность инкапсуляции, но имеют иную природу). Это, в частности, влечёт за собой различия в терминологии в разных источниках. В сообществе C++ или Java, PHP принято рассматривать инкапсуляцию без сокрытия как неполноценную. Однако, некоторые языки (например, Smalltalk, Python) реализуют инкапсуляцию, но не предусматривают возможности сокрытия в принципе. Другие (Standard ML , OCaml) жёстко разделяют эти понятия как ортогональные и предоставляют их в семантически различном виде (см. сокрытие в языке модулей ML).

Подробности

править

Термин «инкапсуляция» может означать следующее в разных языках программирования:

  • механизм языка, ограничивающий доступ одних компонентов программы к другим;
  • языковая конструкция, связывающая данные с методами для их обработки.

Слово «инкапсуляция» происходит от латинского in capsula — «размещение в оболочке». Таким образом, инкапсуляцию можно интуитивно понимать как изоляцию, закрытие чего-либо инородного с целью исключения влияния на окружающее, обеспечение доступности главного, выделение основного содержания путём помещения всего мешающего, второстепенного в некую условную капсулу (чёрный ящик).

Примеры

править

Ada

править
package Stacks is
  
  type Stack_Type is private;
  
  procedure Push (Stack : in out Stack_Type; Val : Integer);
  
private

  type Stack_Data is array (1 .. 100) of Integer;
  
  type Stack_Type is record
    Max : Integer := 0.3;
    Data : Stack_Data;
  end record;
end Stacks;

C++

править
class A
{
 public:
   int a, b; //данные открытого интерфейса
   int Return_Something(); //метод открытого интерфейса
 private:
   int Aa, Ab; //скрытые данные
   void Do_Something(); //скрытый метод
};

Класс А инкапсулирует свойства Aa, Ab и метод Do_Something(), представляя внешний интерфейс Return_Something, a, b.

C#

править

Целью инкапсуляции является обеспечение согласованности внутреннего состояния объекта. В C# для инкапсуляции используются публичные свойства и методы объекта. Переменные, за редким исключением, не должны быть публично доступными. Проиллюстрировать инкапсуляцию можно на простом примере. Допустим, нам необходимо хранить вещественное значение и его строковое представление (например, для того, чтобы не производить каждый раз конвертацию в случае частого использования). Пример реализации без инкапсуляции таков:

    class NoEncapsulation
    {
        public double ValueDouble;
        public string ValueString;
    }

При этом мы можем отдельно изменять как само значение Value, так и его строковое представление, и в некоторый момент может возникнуть их несоответствие (например, в результате исключения). Пример реализации с использованием инкапсуляции:

    class EncapsulationExample
    {
        private double valueDouble;
        private string valueString;

        public double ValueDouble
        {
            get { return valueDouble; }
            set 
            {
                valueDouble = value;
                valueString = value.ToString();
            }
        }

        public string ValueString
        {
            get { return valueString; }
            set 
            {
                double tmp_value = Convert.ToDouble(value); //здесь может возникнуть исключение
                valueDouble = tmp_value;
                valueString = value;
            }
        }
    }

Здесь доступ к переменным valueDouble и valueString возможен только через свойства ValueDouble и ValueString. Если мы попытаемся присвоить свойству ValueString некорректную строку и возникнет исключение в момент конвертации, то внутренние переменные останутся в прежнем, согласованном состоянии, поскольку исключение вызывает выход из процедуры.

Delphi

править

В Delphi для создания скрытых полей или методов их достаточно объявить в секции private.

  TMyClass = class
  private
    FMyField: Integer;
    procedure SetMyField(const Value: Integer);
    function GetMyField: Integer;
  public
    property MyField: Integer read GetMyField write SetMyField;
  end;

Для создания интерфейса доступа к скрытым полям в Delphi введены свойства.

PHP

править
class A
{
    private string $a; // скрытое свойство
    private int $b; // скрытое свойство

    private function doSomething(): void //скрытый метод
    {
        //actions
    }

    public function returnSomething(): int //открытый метод
    {
        //actions
    }
}

В этом примере у класса А закрыты свойства $a и $b с целью предотвращения повреждения этих свойств другим кодом, которому необходимо предоставить только права на чтение.

Java

править

В Java инкапсуляция понимается как механизм, связывающий код и данные, которыми он манипулирует, защищая оба этих компонента от внешнего вмешательства и злоупотреблений. Инкапсуляцию можно считать защитной оболочкой, которая предохраняет код и данные от произвольного доступа со стороны другого кода, находящегося снаружи оболочки. Доступ к коду и данным, находящимся внутри оболочки, строго контролируется тщательно определённым интерфейсом. В Java основой инкапсуляции является класс[1].

class First {
 private int a;
 private int b;
 private void doSomething() { //скрытый метод
  //actions
 }

 public int getSomething() { //открытый метод
  return a;
 } 
}

JavaScript

править
let A = function() {
 // private
 let _property;
 let _privateMethod = function() { /* actions */ } // скрытый метод

 // public
 this.getProperty = function() { // открытый интерфейс
  return _property;
 }

 this.setProperty = function(value) { // открытый интерфейс
  _property = value;
  _privateMethod();
 }
}

или

let A = function() {
 // private
 let _property;
 let _privateMethod = function() { /* actions */ } // скрытый метод

 // public
 return {
  }
 }

или используя приватные свойства

class A {
    #property;
    #privateMethod = () => {
        /* actions */
    }
    
    get property() { // геттер
        return this.#property;
    }
    set property(value) { // сеттер
        this.#property = value;
    }
}
  1. Герберт Шилдт. Java. Полное руководство = The complete reference. Java / Тригуб С.Н.. — 8. — Санкт-Петербург: ООО "И.Д. Вильямс", 2012. — С. 52,53. — 1102 с. — (Oracle Press). — 1500 экз. — ISBN 978-5-8459-1759-1.

📚 Artikel Terkait di Wikipedia

Приведение типа

Приведе́ние (преобразование) ти́па (англ. type conversion, typecasting) — в информатике преобразование значения одного типа в значение другого типа. Выделяют

Логический тип

да́нных, или булев тип, или булевый тип (от англ. Boolean или logical data type) — примитивный тип данных в информатике, принимающий два возможных значения

Полиморфизм (информатика)

полиморфный список» и двух функций над ним: data List a = Nil | Cons a (List a) length :: List a -> Integer length Nil = 0 length (Cons x xs) = 1 + length

Поле класса

обращаться к отдельным битам памяти. }; type foo = class private x: Integer; // закрытое поле public y: Integer; // открытое поле // для доступа к закрытому

Wake-on-LAN

implementation {$R *.dfm} type TMACAddress = packed record case integer of 0: (s1,s2,s3,s4,s5,s6 : byte; ); 1: (cmp1:word; cmp2:integer;); end; TWakeupMagicPacket

Массив (тип данных)

другого массива). Объявление типа «массив» в языке Паскаль type TArrayType = array [0..9] of Integer; (* Массивы, имеющие заданные параметры: 1. Размер — 10

Haskell

алгебраические типы определяются ключевым словом data. Синонимы типов определяются ключевым словом type. -- Алгебраический тип-сумма Масть («перечисление»)

Фабричный метод (шаблон проектирования)

= 2; var Creators: array[1..Count] of TCreator; Product: TProduct; I: Integer; begin // An array of creators Creators[1] := TConcreteCreatorA.Create;