Інкапсуляція (програмування)

У мовах програмування інкапсуляція має одне з наступних значень, або їх комбінацію:

  • мовної механізм обмеження доступу до певних компонентів об'єкта;
  • мовна конструкція сприяюча об'єднанню даних з методами (або іншими функціями), обробними ці дані.

Інкапсуляція - один з чотирьох найважливіших механізмів об'єктно-орієнтованого програмування (поряд з абстракцією, поліморфізмом і спадкуванням).

У той же час, в мовах підтримуючих замикання, інкапсуляція розглядається як поняття не властиве винятково об'єктно-орієнтованому програмуванню. Також, реалізації абстрактних типів даних (наприклад, модулі) пропонують схожу модель інкапсуляції.

Приховування реалізації доцільно застосовувати в таких цілях:

  • гранична локалізація змін при необхідності таких змін,
  • прогнозованість змін (які зміни в коді потрібно зробити для заданого зміни функціональності) і прогнозованість наслідків змін.

1. Приклади

1.1. C + +

 class  A  {  public  :  int  a, b  ;  / / Дані відкритого інтерфейсу  int  ReturnSomething  (  )  ;  / / Метод відкритого інтерфейсу  private  :  int  Aa, Ab  ;  / / Приховані дані  void  DoSomething  (  )  ;  / / Прихований метод  }  ; 

Клас А інкапсулює властивості Aa, Ab і метод DoSomething, представляючи зовнішній інтерфейс ReturnSomething, a, b.

1.2. C #

Метою інкапсуляції є забезпечення узгодженості внутрішнього стану об'єкта. В C # для інкапсуляції використовуються публічні властивості і методи об'єкта. Змінні, за рідкісним винятком, не повинні бути публічно доступними. Проілюструвати інкапсуляцію можна на простому прикладі. Припустимо, нам необхідно зберігати дійсне значення і його строкове представлення (наприклад, для того, щоб не проводити кожен раз конвертацію в разі частого використання). Приклад реалізації без інкапсуляції такий:

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

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

 class  EncapsulationExample  {  private  double  valueDouble  ;  private  string  valueString  ;  public  double  Value  {  get  {  return  valueDouble  ;  }  set  {  valueDouble  =  value  ;  valueString  =  value  .  ToString  (  )  ;  }  }  public  string  ValueString  {  get  {  return  valueString  ;  }  set  {  double  tmp_value  =  Convert  .  ToDouble  (  ValueString  )  ;  / / Тут може виникнути виключення  valueDouble  =  tmp_value  ;  valueString  =  ValueString  ;  }  }  } 

Тут доступ до змінних valueDouble і valueString можливий тільки через властивості Value і ValueString. Якщо ми спробуємо привласнити властивості ValueString некоректну рядок і виникне виключення в момент конвертації, то внутрішні змінні залишаться в колишньому, узгодженому стані, оскільки виключення викликає вихід з процедури.


1.3. Delphi

В Delphi для створення прихованих полів або методів їх достатньо оголосити в секції private.

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

Для створення інтерфейсу доступу до прихованих полях у Delphi введені властивості.


1.4. PHP5

 class  A  {  private  $ A  ;  / / Приховане властивість  private  $ B  ;  / / Приховане властивість  private  function  DoSomething  (  )  / / Прихований метод  {  / / Actions  }  public  function  ReturnSomething  (  )  / / Відкритий інтерфейс  {  / / Actions  }  }  ; 

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


1.5. Java

 class  A  {  private  int  a  ;  private  int  b  ;  private  void  doSomething  (  )  {  / / Прихований метод  / / Actions  }  public  int  returnSomething  (  )  {  / / Відкритий метод  return  a  ;  }  } 

1.6. JavaScript

 A  =  function  (  )  {  / / Private  var _property  ;  var _privateMethod  =  function  (  )  {  / * Actions * /  }  / / Прихований метод  / / Public  this  .  getProperty  =  function  (  )  {  / / Відкритий інтерфейс  return  _property  ;  }  this  .  setProperty  =  function  (  value  )  {  / / Відкритий інтерфейс  _property  =  value  ;  _privateMethod  (  )  ;  }  }