В предыдущей статье мы подробно обсуждали абстракцию. Абстракция, как вы уже поняли, скрывает детали реализации от пользователя и предоставляет только тот интерфейс, который требуется пользователю.
А в этой статье мы обсудим еще одну важную особенность ООП, т.е. инкапсуляцию. Абстракция и инкапсуляция идут рука об руку. Фактически можно сказать, что инкапсулированный код помогает нам в абстракции. В общем, инкапсуляция и абстракция тесно связаны друг с другом. А это значит, что мы можем обсудить эти две концепции вместе, поскольку между инкапсуляцией и абстракцией находится очень тонкая грань.
Что такое инкапсуляция?
Инкапсуляция данных относится к процессу связывания вместе данных и функций или методов, работающих с этими данными, в единое целое, чтобы защитить их от внешнего вмешательства и неправильного использования.
Это важная концепция объектно-ориентированного программирования, которая ведет к еще одной концепции ООП, известной как «скрытие данных». Инкапсуляция скрывает данные и их элементы, тогда как абстракция предоставляет пользователю только необходимые детали или интерфейсы.
В некотором смысле абстракция представляет «абстрактный взгляд» на скрытые данные для пользователя.
Класс в C++ — это тот класс, в котором мы объединяем элементы данных, а функции, работающие с этими элементами данных, вместе со спецификаторами доступа, такими как private, public и protected, представляют собой инкапсуляцию. Мы уже обсуждали спецификаторы доступа в нашей предыдущей статье по классам и объектам.
Вы также должны знать, что по умолчанию, члены класса являются закрытыми. Когда мы объявляем члены класса как частные, а методы для доступа к членам класса как общедоступные, мы действительно реализуем инкапсуляцию. В то же время мы предоставляем пользователю абстрактное представление данных в виде публичных методов.
Реализация инкапсуляции
Инкапсуляция в C++ реализована как класс, объединяющий данные и функции, работающие с этими данными. В основном данные объявляются как частные, чтобы они не были доступны за пределами класса. Методы или функции объявлены общедоступными, и к ним можно получить доступ с помощью объекта класса.
Однако мы не можем получить прямой доступ к закрытым членам, и это называется сокрытием данных. Когда это сделано, данные защищены и могут быть доступны только для функций того конкретного класса, в котором данные объявлены.
Вот пример программы:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
#include <iostream> #include <string> using namespace std; //пример класса демонстрирующий инкапсуляцию class sampleData{ int num; char ch; public: //методы считывания значений данных int getInt() const{ return num; } char getCh() const{ return ch; } //методы настройки установки значений данных void setInt(int num) { this->num = num; } void setCh(char ch){ this->ch = ch; } }; int main() { sampleData s; s.setInt(100); s.setCh('Z'); cout<<"num = "<<s.getInt()<<endl; cout<<"ch = "<<s.getCh(); return 0; } |
Вывод данных:
num = 100 ch = Z |
В приведенной выше программе мы объединили две переменные-члены вместе с методами получения и установки в класс. Это правильный пример инкапсуляции.
Мы объявили две переменные, т.е. num и ch, как частные переменные, чтобы они были недоступны для пользователя. Они доступны только для функций, которые мы объявили общедоступными. Таким образом, у нас есть скрытые элементы данных в качестве частных переменных в классе.
Давайте рассмотрим еще один пример для лучшего понимания инкапсуляции в C++:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 |
#include <iostream> #include <string> using namespace std; //Класс счетов: включает информацию о заработной плате для конкретного сотрудника class Accounts{ int empId; double salary, basic, allowances, deductions; public: Accounts(int empId):empId(empId){} //информация о зарплате void readEmployeeInfo(int empId){ cout<<"Enter basic for the employee"<<empId<<":"; cin>>basic; cout<<"allowances:"; cin>>allowances; cout<<"deductions:"; cin>>deductions; } //рассчитывание заработной платы double calculateSalary(){ salary = basic+ allowances - deductions; return salary; } //отображение подробной информации void display(){ salary = calculateSalary(); cout<<"Employee: "<<empId<<endl; cout<<"Salary: "<<salary; } }; int main() { Accounts acc(1); acc.readEmployeeInfo(1); acc.display(); } |
Вывод данных:
Enter basic for the employee1:10000 allowances:4324.43 deductions:1000 Employee: 1 Salary: 13324.4 |
Это еще один пример инкапсуляции. Как показано выше, у нас есть класс Accounts, который объединяет данные аккаунта и все функции, работающие с этими данными, в один класс Accounts. В основной функции мы можем создать объект этого класса и получить доступ к функциям для получения нужной информации.
Теперь, если некоторые другие классы говорят, что сведения о сотруднике хотят получить доступ к данным учетных записей, то они не могут сделать это напрямую. Им нужно будет создать объект класса Accounts и тогда, они смогут получить доступ только к тем элементам, которые являются общедоступными. Таким образом, используя инкапсуляцию, мы гарантируем контроль доступа к данным, а также обеспечиваем целостность данных.
Разница между инкапсуляцией и абстракцией
Абстракция и инкапсуляция тесно связаны друг с другом. Инкапсуляция помогает абстракции, объединяя данные и методы, работающие с этими данными, вместе.
Инкапсуляция | Абстракция |
Скрывает данные | Скрывает реализацию |
Объединяет данные и методы вместе | Предоставляет пользователю абстрактный интерфейс, предоставляющий только то, что требуется |
Помощь абстракции | Помогает в повторном использовании и безопасности кода |
Реализована как класс со спецификаторами доступа, определяющими доступ к элементам данных и методам. | Реализована как абстрактный класс и интерфейсы, которые не могут быть созданы. |
Итог
Инкапсуляция — одна из наиболее важных функций ООП, поскольку она дает возможность скрыть данные. Это, в свою очередь, делает данные более безопасными и защищает их от злонамеренного использования.
Инкапсуляция помогает абстракции, так что мы можем предоставить конечному пользователю только необходимый интерфейс и соответственно скрыть другие детали.
В нашей следующей статье мы обсудим важность наследования в С++ с соответствующими примерами.
С Уважением, МониторБанк