Инкапсуляция - это механизм, который объединяет данные и код, и защищает и то и другое от внешнего вмешательства или неправильного использования. В ООП код и данные могут быть объединены вместе; в этом случае говорят, что создается так называемый «черный ящик». Все необходимые данные и коды находятся внутри его, то есть создается объект. Другими словами, объект - это то, что поддерживает инкапсуляцию. Внутри объекта коды и данные могут быть закрытыми (private) или открытыми (public). По умолчанию действует принцип private. Закрытые коды или данные недоступны для тех частей программы, которые существуют вне объекта. В случае public коды и данные доступны для всех частей программы. Характерной чертой является ситуация, когда открытая часть объекта используется для того, чтобы обеспечить контролируемый интерфейс с его закрытой частью. Рассмотрим такое важное понятие как класс.
Класс - это механизм для создания объектов. Синтаксис описания класса на С++ похож на синтаксис описания структуры.
|
|
class имя класса {
закрытые функции и переменные класса
public:
открытые функции и переменные класса
} список объектов;
В описании класса список объектов не является обязательным. Функции и переменные, объявленные внутри класса, становятся членами этого класса. По умолчанию, все функции и переменные, объявленные в классе, становятся закрытыми для этого класса. Все функции и переменные, объявленные после слова public, доступны как для членов класса, так и для любой другой части программы, в которой содержится класс.
Пример. В качестве простого примера рассмотрим программу, в которой используется myclass, описанный в тексте для задания значения a для объектов ob1 и ob2 и вывода на экран этих значений для каждого объекта:
# include <iostream.h>
class myclass {
int a; // закрыто вне myclass
public:
void set_a(int num); // член -функция
int get_a(); // член - функция
};
void myclass:: set_a(int num)
{
a = num;
}
int myclass:: get_a()
{
return a;
}
main()
{
myclass ob1,ob2;
ob1.set_a(10);
ob2.set_a(99);
cout << ob1.get_a() <<’’\n’’;
cout << ob2.get_a() <<’’\n’’;
return 0;
}
Как и следовало ожидать, программа выводит на экран величины 10 и 99. Переменная a в myclass является закрытой. Это означает, что она доступна только для функций членов myclass. Например, такое обращение вызовет ошибку
# include <iostream.h>
class myclass {
int a; // закрыто для myclass
public:
void set_a(int num);
int get_a();
};
main()
{
myclass ob1,ob2;
ob1.a=10; // ОШИБКА! К закрытому члену нет доступа
ob2.a=99; // ОШИБКА! К закрытому члену нет доступа
cout << ob1.get_a() <<’’\n’’;
cout << ob2.get_a() <<’’\n’’;
return 0;
}
Пример. Рассмотрим использование открытых переменных
# include < iostream.h>
class myclass {
public:
int a; // теперь а открыта и не нужны set_a() и get_a()
|
|
};
main()
{
myclass ob1,ob2;
ob1.a = 10;
ob2.a = 99;
cout << ob1.a << ‘’\n’’;
cout << ob2.a <<’’\n’’;
return 0;
}
Рассмотрим пример, в котором создается класс - stack, реализующий стек, использующийся для хранения символов:
# include <iostream.h>
# define SIZE 10
class stack {
char stck[SIZE]; // содержит стек
int tos; // индекс вершины стека
public:
void init(); // инициализация стека
void push(char ch); // помещает в стек символ
char pop(); // выталкивает из стека символ
};
void stack::init() // инициализация стека
{
tos=0;
}
void stack::push(char ch) // помещение символа в стек
{
if (tos==SIZE) {
cout << ‘’Стек полон’’;
return;
}
stck[tos] = ch;
tos++;
}
char stack:: pop() // выталкивание символа из стека
{
if(tos==0) {
cout <<’’Стек пуст’’;
return 0; // Возврат нуля при пустом стеке
}
tos--;
return stck[tos];
}
main()
{
stack s1,s2; // создание двух стеков
int i;
s1.init(); // инициализация стека
s2.init();
s1.push(‘a’); // заполнение стека
s2.push(‘x’);
s1.push(‘b’);
s2.push(‘y’);
for(i=0;i<2;i++) cout <<’’символ из s1:’’<<s1.pop() <<’’\n’’; // выталкивание из стека
for(i=0;i<2;i++) cout <<’’символ из s2:’’<<s2.pop() <<’’\n’’;
return 0;
}
Эта программа выводит на экран следующее:
символ из s1: b
символ из s1: a
символ из s2: y
символ из s2: x.