Инкапсуляция (программирование)
Инкапсуляция — механизм языка программирования, который ограничивает доступ к составляющим объект компонентам (методам и переменным), делает их приватными, т.е. доступными только внутри объекта. Важно понимать, что к инкапсулированной переменной можно обратиться, когда пишешь реализацию класса, но при самом его использовании доступа не будет.
Это важный инструмент ООП наряду с полиморфизмом, Наследованием и Абстракцией данных.
В то же время, в языках поддерживающих замыкания, инкапсуляция рассматривается как понятие не присущее исключительно объектно-ориентированному программированию. Также, реализации абстрактных типов данных (например, модули) предлагают схожую модель инкапсуляции.
Содержание |
Область применения [править]
Сокрытие реализации целесообразно применять в следующих целях:
- При необходимости максимальной локализации предстоящих изменений, когда изменяется только работа объекта, а не программы;
- При необходимости предсказания предстоящих изменений и их последствий;
- Необходимость очистки глобальной области видимости.
Примеры [править]
C++ [править]
class A { public: int a, b; //данные открытого интерфейса int ReturnSomething(); //метод открытого интерфейса private: int Aa, Ab; //скрытые данные void DoSomething(); //скрытый метод };
Класс А инкапсулирует свойства Aa, Ab и метод DoSomething, представляя внешний интерфейс ReturnSomething, a, b.
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 некорректную строку и возникнет исключение в момент конвертации, то внутренние переменные останутся в прежнем, согласованном состоянии, поскольку исключение вызывает выход из процедуры.
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 returnSomething() { //открытый метод return a; } }
JavaScript [править]
A = function() { // private var _property; var _privateMethod = function() { /* actions */ } // скрытый метод // public this.getProperty = function() { // открытый интерфейс return _property; } this.setProperty = function(value) { // открытый интерфейс _property = value; _privateMethod(); } }

