Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Лекции по Технологии разработки ПО 2005.doc
Скачиваний:
0
Добавлен:
01.05.2025
Размер:
833.54 Кб
Скачать

Объектно-ориентированное программирование. Классы

Основными свойствами ООП являются инкапсуляция, наследование и полиморфизм. Инкапсуляцией называется объединение данных с функциями их обработки в сочетании со скрытием не нужной для использования этих данных информации. Инкапсуляция позволяет использовать класс в другом окружении и создавать библиотеки классов для применения во многих программах. Наследование – это возможность создания иерархии классов, когда потомки (производные классы) наследуют все свойства своих предков (базовых классов), могут их изменять и добавлять новые. Свойства при наследовании повторно не описываются, что сокращает объём программы. Третьим китом, на котором стоит ООП, является полиморфизм – возможность использовать в различных классах иерархии одно имя для обозначения сходных по смыслу действий и гибко выбирать требуемое действие во время выполнения программы.

Для работы с собственными типами данных требуются специальные функции. Естественно сгруппировать их с описанием этих типов данных в одном месте, а также отделить от её остальных частей.

Класс является абстрактным типом данных, определяемым пользователем, и представляет собой модель реального объекта в виде данных и функций для работы с ними. Данные класса называются полями (по аналогии с полями структуры), а функции класса – методами. Поля и методы называются элементами класса. Описание класса выглядит так:

class Имя {

private:

описание скрытых элементов

public:

описание доступных элементов

};

Спецификаторы доступа private и public управляют видимостью элементов класса. Элементы, описанные после служебного слова private, видимы только внутри класса. Интерфейс класса (методы) описывается после спецификатора public и доступен за пределами класса. Действие любого спецификатора распространяется до следующего спецификатора или до конца класса. Здесь раскрывается ключевая особенность ООП – возможность сокрытия данных, т.е. данные могут быть заключены внутри класса и защищены от несанкционированного доступа функций, расположенных вне класса.

Поля класса:

  • могут иметь любой тип, кроме типа этого же класса (но могут быть указателями или ссылками на этот класс);

  • могут быть описаны с модификатором const, при этом они инициализируются только один раз (с помощью конструктора) и не могут изменяться.

Инициализация полей при описании не допускается! Классы могут быть глобальными (объявленными вне любого блока) и локальными (объявленными внутри блока, например, функции или другого класса).

Приведём простой пример, содержащий класс и два объекта этого класса:

class SmallObj { // определение класса

private:

int data; // поле класса

public:

void setdata(int d) { // метод класса, изменяющий значение поля

data = d;

}

void showdata() { // метод класса, отображающий на экран значение поля

cout << " Znachenie polya ravno " << data << endl;

}

};

//---------------------------------------------------------------------------

int main() {

SmallObj s1, s2; // определение двух объектов класса SmallObj

s1.setdata(2001); // вызов метода setdata (инициализация)

s2.setdata(2002);

s1.showdata(); s2.showdata(); // вызов метода showdata (вывод на экран)

getch(); return 0;

}

Класс SmallObj, определённый в этой программе, содержит одно поле данных и два метода. Методы обеспечивают доступ к полю данных класса. Нельзя обратиться к полю класса из главной функции, поскольку доступ к полям возможен только из методов класса. Объединение данных и функций является стержневой идеей ООП (см. рис.).

Класс

Объект находится в таком же отношении к своему классу, в каком переменная находится по отношению к своему типу. Как правило, скрывая данные класса, его методы оставляют доступными. Это объясняется тем, что данные скрывают с целью избежать нежелательного внешнего воздействия на них, а функции, работающие с этими данными, должны обеспечивать взаимодействие между данными и внешней по отношению к классу частью программы. Тем не менее, не существует чёткого правила, которое бы определяло, какие данные следует определять как private, а какие функции – как public.

Вы можете столкнуться с ситуациями, когда будет необходимо скрывать функции и обеспечивать свободный доступ к данным класса. Например, если поле класса сделать открытым public: int data; , то в главной функции можно получать доступ к этому полю по аналогии со структурами s2.data = 25; .

Из приведённого выше примера видно, что для получения доступа к методу класса необходимо использовать операцию точки (.), связывающую метод с именем объекта. Синтаксически это напоминает доступ к полям структуры, но в данном случае мы совершаем вызов функции, а не используем значение переменной. Оператор s1.setdata(2001); вызывает метод setdata() объекта s1 . Метод присваивает полю somedata объекта s1 значение, равное 2001. Аналогично, два вызова функции showdata() отобразят на экране значения полей соответствующих объектов.

Рассмотрим пример создания класса, основой для которого послужит структура Tovar, рассматривавшаяся нами ранее и содержащая информацию о товарах на складе.

const int N=30;

class Tovar {

private:

char name[N];

int number;

float cena;

public:

void setdata(char* tname, int tnum, float tcen) {

strcpy(name, tname);

number = tnum;

cena = tcen;

}

void showdata() {

cout << "\nNaimenovanie tovara: " << name;

cout << "\nNomer tovara: " << number;

cout << "\nStoimost tovara: " << cena;

}

};

int main() {

Tovar t1, t2;

t1.setdata("Sanki der.", 1100, 231.45); //инициализация значений

t1.showdata();

t2.setdata("Konki beg.", 2211, 134.90);

t2.showdata();

getch(); return 0;

}

В данном примере имеется возможность инициализировать поля класса только в программе. Для получения возможности вводить значения полей класса пользователем необходимо создать в классе соответствующий метод.

class Tovar {

private:

public:

void setdata(char* tname, int tnum, float tcen) {

}

void getdata() {

cout << "\n Vvedite naimenovanie tovara: "; cin.getline(name, N);

cout << " Vvedite nomer tovara: "; cin >> number;

cout << " Vvedite stoimost tovara: "; cin >> cena;

}

void showdata() {

}

};

int main() {

Tovar t1, t2, t3;

t3.getdata(); //позволяет вводить данные пользователем

t3.showdata();

getch(); return 0;

}