Раздел «Язык Си».ClassIer1:

Наследование

В задаче про работников и ворон в классах 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(); // вороны воруют яблоки из корзины
};

REFACTOR Задачи

REFACTOR Задача 1

Реализовать и проверить класс Crow

REFACTOR Задача 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();
};

REFACTOR Задачи

REFACTOR Задача 3

Реализовать функции класса Customer. Если яблок в корзине нет, покупатель яблоки не берет.

REFACTOR Задача 4

Написать программу-модель. 5 рабочих собирают яблоки 8 часов, 3 вороны воруют яблоки, 4 покупателя четыре часа собирают яблоки вместе с рабочими, а потом каждый один раз покупает яблоки . Если яблок в корзине нет, покупатель яблоки не берет.

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

-- TatyanaOvsyannikova2011 - 26 Feb 2016

Attachment sort Action Size Date Who Comment
nasl1.png manage 37.1 K 26 Feb 2016 - 16:15 TatyanaOvsyannikova2011