Инкапсуляция - это одна из трех основных особенностей объектно-ориентированного программирования (ООП). Две другие - полиморфизм и наследование. Вместе они составляют базу ООП, определяющую целый спектр возможностей написания программ на разных языках, используя эти три принципа. Объектно-ориентированные языки, в свою очередь, обязаны четко им следовать.
Основы ООП
Объектно-ориентированное программирование стоит на трех китах своего мироздания:
- Полиморфизме, отвечающем на вопрос, как определенный язык программирования трактует объекты, имеющие между собой связь, сходным образом.
- Наследовании, дающем ответ, каким образом происходит стимуляция использования кода многократно.
- Инкапсуляции, являющейся ответом на вопрос, как происходит сокрытие реализации, а значит и сохранения целостности данных.
Терминология
Инкапсуляция (программирование) - это использование модификаторов доступа с целью сокрытия частей программного кода от конечного пользователя. Под ним, в свою очередь, подразумевается разработчик или наследующий объект.
Суть понятия "инкапсуляция"
Дефиниция определяет, что под инкапсуляцией подразумевается сокрытие всего или части программного кода. Суть же понятия "инкапсуляция" заключается в манипулировании модификаторами доступа. Это означает, что разработчик сам решает, какие свойства, методы и классы будут открыты классу-клиенту, а какие - скрыты.
Модификаторы доступа
Существуют такие модификаторы доступа, которыми, в числе прочих, способна манипуляривать инкапсуляция (программирование Java):
- public ("паблик" - публичный, открытый, доступ) - общий доступ как для текущих объектов и классов, так и для внешнего мира;
- private ("прайват" - приватный, частный, скрытый доступ) - закрытый доступ, суть которого полностью противоположна предыдущему. Обеспечивает доступ только из текущего класса;
- protected ("протектед" - защищенный, полускрытый, доступ) - доступ для текущего класса и производных от него;
- по умолчанию - неуказанный модификатор доступа подразумевает, что поле/метод видно для всего текущего пакета классов.
В языке C# ("Си Шарп"), помимо указанных (исключая последний), есть еще такие модификаторы:
- internal ("интернал" - внутренний доступ) - общедоступность в текущем сборе, закрытый доступ по всем остальным случаям;
- internal protected ("интернал протектед" - внутренний защищенный доступ) - объединение двух модификаторов в один, в котором проявляются свойства обоих из них.
Роль инкапсуляции
Механизм инкапсуляции позволяет исключить внешнее влияние на программный код и неверное использование заложенных в нем данных. Это происходит за счет объединения кода и данных в одно целое.
Объект и инкапсуляция
Объединение реализации программного модуля и данных, заложенных в коде, в программировании называется объектом. Суть связи его с инкапсуляцией заключается в том, что именно такая методика позволяет поддерживать и обеспечивать целостное функционирование рассматриваемого механизма.
Преимущество инкапсуляции
Инкапсуляция - это способ упростить процесс кодирования. Многочисленные строки кода остаются "за кулисами", а в основном классе работа идет с экземплярами объектов.
Идея защиты данных
Инкапсуляция - это также механизм, который реализует идею защиты данных. Программная логика объектно-ориентированного программирования построена на базе того, что большая часть данных будет скрыта модификатором доступа private (приватный, частный) или protected (защищенный). Внешний мир, клиент случайно или преднамеренно не смогут повредить реализации программного модуля. Поскольку на самом деле сделать это очень легко даже не нарочно, инкапсуляция - это очень хороший принцип.
Единицы инкапсуляции
Класс, как основная единица инкапсуляции, описывает данные и содержит код, который этими данными способен оперировать. Также он является базой для построения объекта. Последний, в свою очередь, представлен как экземпляр класса.
Используется также следующая терминология:
- члены - это код и данные, входящие в класс;
- поля, или переменные экземпляра - так называются данные, которые определяет класс;
- функции-члены - в них содержится сам код. Функции-члены - общее название. Частный случай - методы.
Инкапсуляция на конкретном примере
Инкапсуляция (программирование) пример:
* Примечание:
description - это описание метода/свойства/переменной, то есть комментирование того, что, собственно, происходит в программе. Продемонстрировано при помощи открывающихся/закрывающихся тегов
using System-
namespace OOPLibrary.Auto
{
///
/// Данный класс предназначен для того, чтобы описывать свойства и действия автомобиля
///
public class Auto
{
///
/// Переменная, созданная для того, чтобы в нее записывать, сколько автомобилю лет, так как внешнее вмешательство в это свойство разработчик считает лишним
/// оно помечается модификатором private, то есть закрытый, частный доступ (см. описание выше).
///
private int _age-
///
/// Булевская переменная (только два возможных значения - либо да, либо нет), которая описывает, движется ли автомобиль на данный момент
/// Она также не должна быть открыта для конечного пользователя, кем бы он ни был. Потому и этой переменной присваивается закрытый модификатор доступа "прайват"
///
private bool _isMoving-
///
/// В данной строковой переменной должна содержаться информация о цвете автомобиля. Он может подвергаться изменениям со стороны внешнего воздействия
/// потому для Цвета выбран модификатор открытого доступа "паблик".
///
public string Color-
///
/// В данном конкретном случае допускаем, что имя автомобиля тоже можно менять
/// присваивается модификатор паблик (открытый доступ для всех, вне зависимости от класса или сборки).
///
public string Name-
///
/// Открывается конструктор класса и все свойства, выраженные переменными и заданные чуть ранее, получают свои значения
///
public Auto()
{
Видео: Объектно-Ориентированное Программирование
_age = 5-
_isMoving = false-
Color = "Фиолетовый"-
Name = "Шкода Октавиа"-
}
///
/// Метод реализует возврат значения возраста авто. Зачем это необходимо?
/// закрытый модификатор доступа не делает его возможным для изменения клиентом.
///
/// Возвращает возраст автомобиля.
public string GetAge()
{
return "На данный момент выбранной машине" + _age + " лет."-
}
Видео: OOP and Design Patterns (урок 3) - Инкапсуляция и спецификаторы доступа
///
/// Если автомобиль не движется, этот метод реализует старт движения. Выполняется проверка переменной, обознающей, в каком состоянии находится автомобиль (едет он или нет), и, в зависимости от результатов, выполняется соответствующее действие/выводится соответствующее сообщение.
///
public void Start()
{
if (_isMoving)
{
Console.WriteLine("Движение уже было начато")-
}
else
{
_isMoving = true-
Console.WriteLine("На старт, внимание.. Вперед! Поехали!")-
}
}
///
/// Если движение было начато, то этот метод его останавливает. Та же программная логика, что и в предыдущем рассмотренном случае.
///
public void Stop()
{
if (_isMoving)
{
_isMoving = false-
Console.WriteLine("Стоп, машина")-
}
else
{
Console.WriteLine("Ошибка. Автомобиль и так стоит на месте, не движется")-
}
}
///
/// Осуществляется поворот налево, если имеет место движения автомобиля
Видео: Что такое инкапсуляция? Заблуждения об инкапсуляции
///
public void MoveLeft()
{
if (_isMoving)
{
Console.WriteLine("Осуществлен поворот налево")-
}
else
{
Console.WriteLine("Ошибка. Автомобиль стоит на месте. Функция поворота на данный момент недоступна")-
}
}
///
/// Аналогичный метод с поворотом направо
///
public void MoveRight()
{
if (_isMoving)
{
Console.WriteLine("Поворот направо был осуществлен успешно")-
}
else
{
Console.WriteLine("Ошибка. Автомобиль еще не двигался с места. Поворот направо является на данный момент действием, невозможным для выполнения.")-
}
}
}
}