Инкапсуляция (англ. encapsulation, от лат. in capsula) — в информатике упаковка данных и функций в единый компонент.
Инкапсуляция зачастую рассматривается как понятие, присущее исключительно объектно-ориентированному программированию (ООП), но в действительности обширно встречается и в других (см. подтипизация на записях и полиморфизм записей и вариантов). В ООП инкапсуляция тесно связана с принципом абстракции данных (не путать с абстрактными типами данных, реализации которых предоставляют возможность инкапсуляции, но имеют иную природу). Это, в частности, приводит к другому распространённому заблуждению — рассмотрению инкапсуляции неотрывно от сокрытия. В частности, в сообществе С++ или Java принято рассматривать инкапсуляцию без сокрытия как неполноценную. Однако, некоторые языки (например, Smalltalk, Python) реализуют инкапсуляцию в полной мере, но не предусматривают возможности скрытия в принципе. Другие (Standard ML, OCaml) жёстко разделяют эти понятия как ортогональные и предоставляют их в семантически различном в виде (см. сокрытие в языке модулей ML).
В общем случае в разных языках программирования термин «инкапсуляция» относится к одной или обеим одновременно следующим нотациям:
Пренебрегая формализмом и способствуя интуитивному восприятию, инкапсуляцию можно определить с помощью латинского in capsula — размещение в оболочке, изоляция, закрытие чего-либо инородного с целью исключения влияния на окружающее, обеспечение доступности главного, выделение основного содержания путём помещения всего мешающего, второстепенного в некую условную капсулу (чёрный ящик). Однако данное определение является лишь приближением.
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;
class A
{
public:
int a, b; //данные открытого интерфейса
int ReturnSomething(); //метод открытого интерфейса
private:
int Aa, Ab; //скрытые данные
void Do_Something(); //скрытый метод
};
Класс А инкапсулирует свойства Aa, Ab и метод Do_Something(), представляя внешний интерфейс ReturnSomething, a, b.
Целью инкапсуляции является обеспечение согласованности внутреннего состояния объекта. В 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 для создания скрытых полей или методов их достаточно объявить в секции private
.
TMyClass = class
private
FMyField: Integer;
procedure SetMyField(const Value: Integer);
function GetMyField: Integer;
public
property MyField: Integer read GetMyField write SetMyField;
end;
Для создания интерфейса доступа к скрытым полям в Delphi введены свойства.
class A
{
private $a; // скрытое свойство
private $b; // скрытое свойство
private function doSomething() //скрытый метод
{
//actions
}
public function returnSomething() //открытый метод
{
//actions
}
}
В этом примере у класса А закрыты свойства $a и $b с целью предотвращения повреждения этих свойств другим кодом, которому необходимо предоставить только права на чтение.
1 class A {
2 private int a;
3 private int b;
4 private void doSomething() { //скрытый метод
5 //actions
6 }
7
8 public int getSomething() { //открытый метод
9 return a;
10 }
11 }
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();
}
}
}
Для улучшения этой статьи желательно: |
Данная страница на сайте WikiSort.ru содержит текст со страницы сайта "Википедия".
Если Вы хотите её отредактировать, то можете сделать это на странице редактирования в Википедии.
Если сделанные Вами правки не будут кем-нибудь удалены, то через несколько дней они появятся на сайте WikiSort.ru .