Наследование
В задаче про работников и ворон в классах
Worker и
Crow очень похожие функции и атрибуты. Их пришлось переписывать два раза.
Кроме того, есть
общий объект - корзина, которую нужно передавать работникам и воронам как указатель.
Это не очень удобно.
Пусть у нас уже есть класс
Person, у которого есть одинаковый для всех артибут
apple и
статический объект - basket. В этом классе
уже есть общие для работника и ворон функции.
#include <iostream>
#include <cstdlib>
using namespace std;
// Класс, в котором есть общие для работников и ворон
// атрибуты и функции
class Person{
int apple; // яблоки "знают" и работники и вороны
public:
Person(); // конструктор. Количество яблок - случайно
Person(int app); // инициализирующий конструктор.
int getApple(); // возвращает количество яблок
void print(); // печать
// корзина - статический объект
// в области public, значит ее могут использовать все
static int basket;
};
// Сначала в козине 0
int Person::basket=0;
// Реализация
Person::Person(){
apple=rand() % 100;
cout<<"Появился кто-то. Хочет "<<apple<<" яблок в час"<<endl;
};
Person::Person( int app){
// Проверка. Сокращенная запись
// Если app < 0, то яблок - 0, если >=0, то не больше 100
apple=(app < 0)? 0 : app % 100;
cout<<"Появился кто-то. Хочет "<<apple<<" яблок в час"<<endl;
};
// получить яблоки
int Person::getApple(){
return apple;
};
// печать
void Person::print(){
cout<<apple<<" яблок в час"<<endl;
// basket - статическая переменная - общая для всех
// сразу печататем сколько в ней яблок
cout<<" в корзине: "<<basket<<endl;
};
Теперь можно написать новый класс
Worker - наследник класса
Person. У нового класса
Worker уже сразу будут функции:
print(),
getApple() и конструкторы от класса Person
// Объявляем класс Worker как наследник
class Worker:public Person{
public:
// Новый конструктор по-умолчанию
Worker();
// Новый инициализирующий кнструктор
Worker(int app);
// новая функция, ее не было
void act();
};
// Реализация
Worker::Worker(){
// в новом конструкторе можно добавить действий
cout<<"Я работник, я собираю ";
// этот print() уже есть в классе - родителе Person
// его можно просто вызвать.
print() ;
};
// Новый инициализирующий конструктор
// Когда создается объект класса-наследника, сначала всегда создается
// объект класса - родителя.
// apple - в закрытой области класса-родителя, значит
// не доступен Worker/
// Чтобы передать параметры объекьу классса Person,
// нужно ЯВНО вызвать инициализирующий конструктор класса Person
Worker::Worker(int app):Person(app){
cout<<"Я работник, мне сказали собирать ";
print() ;
};
// basket - в открытой области. Можно спокойно им пользоваться
void Worker::act(){
basket += getApple(); // кладет яблоки в корзину.
};
// Пример использования Worker
int main(){
Person p1, p2(220), p3(-3);
Worker a1, a2(30);
a1.act();// работает
a2.act();
a2.act();// работает
a1.print();
// этот print() будет вызван для объекта класса Person,
// а не для Worker
// МОЖНО ПРЕОБРАЗОВЫВАТЬ ОБЪЕКТ к КЛАССУ-РОДИТЕЛЮ
((Person)a2).print();
return 0;
}
Вороны тоже пользуются корзиной и "знают" про яблоки. Можно написать класс
Crow как наследник класса
Person.
class Crow:public Person{
// про яблоки все уже написано в классе Person
public:
Crow(); // конструктор
Crow(int app); // инициализирующий конструктор
void steal(); // вороны воруют яблоки из корзины
};
Задачи
Задача 1
Реализовать и проверить класс
Crow
Задача 2
Работники и вороны в саду 8 часов. Написать программу-модель, чтобы посмотреть сколько яблок в корзине каждый час. Использовать
классы-наследники
Worker и *Crow*/
Область protected
Яблоки, которые собрали работники покупают покупатели. НИКТО кроме работников, ворон и покупателей не должен иметь доступ к корзине.
Для того, чтобы к атрибуту имели доступ только функции классов-наследников есть область
protrcted.
"Спрячем" basket в область
protected
class Person{
int apple;
public:
Person();
Person(int app);
int getApple();
void print();
protected:
// теперь изменять basket могут только
// объекты классов-наследников
static int basket;
}
class Worker:public Person{
public:
Worker();
Worker(int app);
void act();
protected:
// Для денег за яблоки заведем кошелек
static int cache;
};
int Worker::cache = 0;
// класс Покупатель. Он берет яблоки и оставляет в деньги в cache
// имеет доступ к cache
class Customer:public Worker{
// про яблоки уже все известно
int money;
public:
Customer();// конструктор только по-умолчанию, деньги случайно, но <= 20
// покупатель может и собирать яблоки - функция act() у него тоже есть
// берет яблоки и оставляет деньги в cache
void buy();
void print();
};
// класс Crow имеет доступ к basket, но не имеет к cache
class Crow:public Person{
public:
Crow();
Crow(int app);
void act();
};
Задачи
Задача 3
Реализовать функции класса
Customer. Если яблок в корзине нет, покупатель яблоки не берет.
Задача 4
Написать программу-модель. 5 рабочих собирают яблоки 8 часов, 3 вороны воруют яблоки, 4 покупателя четыре часа собирают яблоки вместе с рабочими, а потом каждый один раз покупает яблоки . Если яблок в корзине нет, покупатель яблоки не берет.
Программа должна печатать сколько яблок в корзине каждый час и сколько денег за яблоки достанется каждому, кто их собирал.
--
TatyanaOvsyannikova2011 - 26 Feb 2016