Инкапсуляция (программирование)

Материал из Википедии — свободной энциклопедии
Перейти к: навигация, поиск

Инкапсуляция (лат. in capsula) — механизм языка программирования, ограничивающий доступ к составляющим объект компонентам (методам и свойствам), делает их приватными, то есть доступными только внутри объекта. Является важным инструментом ООП наряду с полиморфизмом, наследованием и абстракцией данных. Например, к инкапсулированной переменной можно обратиться при написании реализации класса, но при его использовании обращение к ней невозможно.

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

Примеры[править | править вики-текст]

C++[править | править вики-текст]

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

Класс А инкапсулирует свойства Aa, Ab и метод Do_Something(), представляя внешний интерфейс ReturnSomething, 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 введены свойства.

PHP5[править | править вики-текст]

class A
{
 private $a; // скрытое свойство
 private $b; // скрытое свойство
 private function DoSomething() //скрытый метод
 {  
  //actions
 }
 
 public function ReturnSomething() //открытый интерфейс
 { 
  //actions
 }
};

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

Java[править | править вики-текст]

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

JavaScript[править | править вики-текст]

var A = function() {
 // private
 var _property;
 var _privateMethod = function() { /* actions */ } // скрытый метод
 
 // public
 this.getProperty = function() { // открытый интерфейс
  return _property;
 }
 
 this.setProperty = function(value) { // открытый интерфейс
  _property = value;
  _privateMethod();
 }
}

или

var A = function() {
 // private
 var _property;
 var _privateMethod = function() { /* actions */ } // скрытый метод
 
 // public
 return {
  getProperty: function() { // открытый интерфейс
   return _property;
  },
  setProperty: function(value) { // открытый интерфейс
   _property = value;
   _privateMethod();
  }
 }
}