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

Иерархия классов

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

В качестве примера рассмотрим базу данных служащих некоторой компании, в которой существует только две категории служащих: менеджеры, занятые управлением, и рабочие, занятые изготовлением товара. В базе данных хранятся имена служащих всех категорий и их идентификационные номера. В информации о менеджерах содержится ещё название их должности и заработная плата, а в информации о рабочих – квалификационный разряд.

Служащий

Имя

Номер

Менеджер

Рабочий

Должность

Зар.плата

Разряд

Программа будет состоять из базового класса, который содержит фамилии служащих и их номера и порождает два новых класса.

const int L = 80;

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

class Sotrudnik { //базовый класс

private:

char name[L];

int number;

public:

void getdata() {

cout << "\n Vvedite FIO: "; cin.getline(name, L);

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

}

void show() const {

cout << "\n Familiya: " << name;

cout << "\n Nomer: " << number;

}

};

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

class Manager : public Sotrudnik { //производный класс

private:

char dolgnost[L];

double oklad;

public:

void getdata() {

Sotrudnik::getdata();

cout << " Vvedite dolgnost: "; cin >> dolgnost;

cout << " Vvedite zarplatu: "; cin >> oklad;

}

void show() const {

Sotrudnik::show();

cout << "\n Dolgnost: " << dolgnost;

cout << "\n Zar. plata: " << oklad;

}

};

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

class Worker : public Sotrudnik {

private:

int raz;

public:

void getdata() {

Sotrudnik::getdata();

cout << " Vvedite razryad: "; cin >> raz;

}

void show() const {

Sotrudnik::show();

cout << "\n Razryad: " << raz;

}

};

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

int main() {

Manager m1;

Worker r1, r2;

cout << "\nVvod managerov: "; m1.getdata(); cin.get();

cout << "\nVvod workerov: "; r1.getdata(); cin.get(); r2.getdata();

cout << "\nVyvod managerov: "; m1.show();

cout << "\nVyvod workerov: "; r1.show(); r2.show();

getch(); return 0;

}

Обратите внимание на то, что данные базового класса объявлены с ключевым словом private. Это вызвано тем, что производным классам нет необходимости использовать эти данные напрямую. Они используют вызов методов базового класса, которые в свою очередь имеют полный доступ к данным.

В данной программе мы не определяли объекты класса Sotrudnik, а использовали его как общий базовый класс для производных классов. Здесь, ни в в базовом, ни в производных классах нет конструкторов, поэтому компилятор использует конструктор по умолчанию производного класса, вызывающий конструктор по умолчанию базового класса.

Вопрос

Что надо добавить в эту программу, чтобы появилсь возможность инициализировать в программе объект класса Worker.

int main() {

Worker r1, r2("Petrov T.I.", 333, 1);

cout << "\nVvod workerov: "; r1.getdata();

cout << "\nVyvod workerov: "; r1.show(); r2.show();

getch(); return 0;

}

Ответ

class Sotrudnik {

private:

char name[L];

int number;

public:

Sotrudnik() {

strcpy(name, "\0");

number = 0;

}

Sotrudnik(char *fio, int n) {

strcpy(name, fio);

number = n;

}

void getdata() {

cout << "\n Vvedite FIO: "; cin.getline(name, L);

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

}

void show() const {

cout << "\n Familiya: " << name;

cout << "\n Nomer: " << number;

}

};

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

class Manager : public Sotrudnik {

};

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

class Worker : public Sotrudnik {

private:

int raz;

public:

Worker() : Sotrudnik() { }

Worker(char *wname, int num, int r) : Sotrudnik(wname, num) {

raz = r;

} // или Worker(char *wname, int num, int r) : Sotrudnik(wname, num), raz(r) { }

void getdata() {

Sotrudnik::getdata();

cout << " Vvedite razryad: "; cin >> raz;

}

void show() const {

Sotrudnik::show();

cout << "\n Razryad: " << raz;

}

};

Варианты написания программы

Вариант 2

При определении производных классов Manager и Worker можно было-бы использовать спецификатор private (частное наследование), например:

class Manager : private Sotrudnik {…}

class Worker : private Sotrudnik {…}

Это можно было сделать, поскольку объекты производных классов, не используют методы базового класса. В методах производных классов используется только вызов методов базового класса.

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

class Manager : public Sotrudnik {

private:

char dolgnost[L];

double oklad;

public:

void getdata() {

Sotrudnik::getdata();

cout << " Vvedite dolgnost: "; cin >> dolgnost;

cout << " Vvedite zarplatu: "; cin >> oklad;

}

// void show() const {…} отсутствует этот метод

};

int main() {

Manager m1;

cout << "\nVyvod managerov: "; m1.show(); // вызовется метод базового класса

}

При необходимости скрыть все методы базового класса от объектов производного класса необходимо применять частное наследование.

Вариант 3

Здесь, в главной функции для ввода данных о первом рабочем мы использовали оператор r1.getdata();. Если в методе getdata() производного класса убрать вызов одноимённого метода базового класса, то тогда в главной функции вместо оператора r1.getdata(); надо было-бы написать следующее: r1.Sotrudnik::getdata(); r1.getdata();. Только в этом случае обязательно необходимо использовать общее наследование, т.е. class Worker : public Sotrudnik { … }; .