
- •1. Временная сложность алгоритмов. Примеры алгоритмов с различной временной сложностью.
- •2. Процедурное и объектно-ориентированное программирование. Основные концепции объектно-ориентированного программирования.
- •3. Класс как тип данных. Поля и методы класса. Создание класса на основе структурного и объединяющего типов данных.
- •6. Классы. Принцип наследования. Создание иерархии классов.
- •7. Наследование полей и методов. Изменение статуса видимости полей и методов при наследовании.
6. Классы. Принцип наследования. Создание иерархии классов.
Классы могут находиться в отношении наследования, при котором формируется иерархия классов, а также иерархия соответствующих им объектов. Иерархия классов позволяет определять новые классы на основе уже имеющихся
. Имеющиеся классы называют базовыми, а также порождающими или родительскими. Новые классы, формируемые на основе базовых, называют производными, а также порожденными или наследниками. Производные классы получают данные и методы своих родителей, а также могут пополняться собственными данными и методами. Наследуемые элементы не перемещаются в производные, а остаются в базовых классах. Запросы, обработку которых не могут выполнить методы производных классов, автоматически передаются в базовый класс. Если для обработки запроса нужны данные, отсутствующие в производном классе, то их автоматически пытаются отыскать в базовом классе. Рассмотрим в качестве примера простой иерархии набор из двух классов – базового и производного. Базовый класс определим следующим образом:
class Base
{ // Базовый класс Человек
Person p;
public:
Base () {...}
Person get() {return p;}
int put (Person x) {...}
};
Здесь p – структура, с полями для хранения имени, фамилии и возраста человека:
struct Person // просто Человек
{
char firstname[10];
char lastname[15];
int age;
};
В базовом классе Base определены открытые методы get и put, обеспечивающие доступ к закрытому полю p, и конструктор класса.
Наследниками базового класса являются производный класс Employee.
Класс Employee определен следующим образом:
class Employee: protected Base
{ // Производный класс Служащий
char post[15];
double salary;
static double percent;
public:
Employee (double x = 0.13) {...}
double payment() {return salary*(1-percent);}
};
В заголовке производного класса после его имени и символа двоеточие указывается имя его непосредственного предка (его базового класса). Кроме разделов private и public, в базовом классе может быть объявлен раздел со статусом видимости protected (защищенный), поля и методы которого доступны лишь для методов его потомков.
7. Наследование полей и методов. Изменение статуса видимости полей и методов при наследовании.
Наследуемые элементы не перемещаются в производные, а остаются в базовых классах. Запросы, обработку которых не могут выполнить методы производных классов, автоматически передаются в базовый класс. Если для обработки запроса нужны данные, отсутствующие в производном классе, то их автоматически пытаются отыскать в базовом классе.
Рассмотрим в качестве примера простой иерархии набор из трех классов – базового и двух производных
Базовый класс определим следующим образом:
class Base
{// Базовый класс Человек
Person p;
public:
Base () {...}
Person get() {return p;}
int put (Person x) {...}
};
Здесь p – структура, с полями для хранения имени, фамилии и возраста человека:
struct Person // просто Человек
{
char firstname[10];
char lastname[15];
int age;
};
В базовом классе Base определены открытые методы get и put, обеспечивающие доступ к закрытому полю p, и конструктор класса.
Наследниками базового класса являются производные классы Student и Employee. Класс Employee определен следующим образом:
class Employee: protected Base
{ // Производный класс Служащий
char post[15];
double salary;
static double percent;
public:
Employee (double x = 0.13) {...}
double payment() {return salary*(1-percent);}
};
В этом классе, кроме унаследованного поля p, определены дополнительные поля post (должность), salary (оклад) и статическое поле percent (процент удержания). В открытой части класса определены конструктор и метод payment, возвращающий значение выплат после вычета удержаний.
Класс Student определен следующим образом:
class Student: public Base // Производный класс
{ short year;
bool grant;
float marks[8];
public:
Student () {…}
short get_year () {…}
bool get_grant () {…}
float get_marks (int i) {…}
int put_year (short x) {…}
void put_grant (bool x) {…}
int put_marks (float x, int i) {…}
};
В этом классе, кроме унаследованного поля p, определены дополнительные поля year (год обучения), grant (стипендия) и поле-массив marks (средние семестровые оценки). В открытой части класса определены конструктор и методы доступа к полям
.
В заголовке производного класса после его имени и символа двоеточие указывается имя его непосредственного предка (его базового класса). Кроме разделов private и public, в базовом классе может быть объявлен раздел со статусом видимости protected (защищенный), поля и методы которого доступны лишь для методов его потомков.
Производный класс наследует все поля и методы базового класса. При этом статус видимости унаследованных элементов базового класса может измениться в классах-потомках.Чтобы этого не произошло перед именем базового класса в заголовке класса-потомка нужно указать спецификатор доступа public:
class Student: public Base
Если перед именем базового класса указать спецификатор доступа private или protected, то открытые члены базового класса перестают быть непосредственно доступными объектам классов- потомков
Например:
class Employee: private Base
Спецификатор private предполагается используемым по умолчанию.