22. Наследяване

Ето родословието на Терах:
Терах стана баща на Аврам, Нахор и Аран,
а Аран стана баща на Лот.
Битие 11:27
Производни класове.
    Наследяването е механизъм за разширяване на вече съществуващи класове. Новият клас наследява съществуващия, като в него се добавят нови членове-функции и полета с данни.
    Базов клас:
class Employee {
public:
   Employee(string emp_name, double init_salary);
   void set_salary(double new_salary);
   string get_name() const;
   double get_salary() const;
   void print() const;
private:
   string name;
   double salary;
};
    Производен клас:
class Manager : public Employee {
public:
   Manager(string n, double sal, string dept);
   string get_department() const;
   void print() const;
private:
   string department;
};
    Конструиране на обект от производния клас:
Manager man("Nino", 670, "Computer Science");
    Извикване на член-функция от производния клас:
man.set_salary(1200);
    Извикване на член-функция от базовия клас:
cout << man.get_department();
    Данните в производния клас:
Manager
Employee
string name;
double salary;

string department;

man
Employee
"Nino"
670

"Computer Science"

Employee - базов клас, Manager - производен клас
- членовете на базовият клас са членове и на производния клас;
- функциите на производният клас нямат достъп  до частните членове на базовия клас


Дефиниции на функции от производния клас.
    Конструкторът на производния клас има две задачи:
- да инициализира полетата с данни;
- да инициализира обекта от базовия клас, който се  съдържа в производния клас..
  Manager::Manager(string n, double sal, string dept)
          : Employee(n, sal)
  { department = dept;  }

    Ако в базовия и в производния класове има функции с едно и също име, то викането на член-функция на базовия клас от функция на производния клас става с помощта на операция "принадлежност към клас" - ::
  void  Manager::print()
  { Employee::print();
    cout << department; }



Пример.  Да се изобразят няколко часовника, които показват часа в различни градове по света. Ще използваме класа Clock от 11. Класове. Производният клас  WorldClock включва допълнителна низова данна за името на съответния град.

// clocks.cpp
#include "ccc_win.cpp"
#include "ccc_time.cpp"
const double PI = 3.141592653589793;

class Clock {
public:
   Clock() {}
   Clock(Point c, double r){ center = c; radius = r; }
   void set_time(Time t){ current_time = t; }
   void draw() const;
private:
   void draw_tick(double angle, double length) const;
   void draw_hand(double angle, double length) const;
   Time current_time;
   Point center;
   double radius;
};

void Clock::draw_tick(double angle, double length) const
{ double alpha = PI/2 - 6*angle*PI/180;
  Point from(center.get_x() + cos(alpha)*radius*(1-length),
             center.get_y() + sin(alpha)*radius*(1-length));
  Point to(center.get_x() + cos(alpha)*radius,
           center.get_y() + sin(alpha)*radius);
  cwin << Line(from, to);
}

void Clock::draw_hand(double angle, double length) const
{ double alpha = PI/2 - 6*angle*PI/180;
  Point from = center;
  Point to(center.get_x() + cos(alpha)*radius*length,
           center.get_y() + sin(alpha)*radius*length);
  cwin << Line(from, to);
}

void Clock::draw() const
{ cwin << Circle(center, radius);
  const double HOUR_TICK = 0.2;
  const double MINUTE_TICK = 0.1;
  const double HOUR_HAND = 0.6;
  const double MINUTE_HAND = 0.75;
  for (int i = 0; i < 12; i++)
  { draw_tick(i * 5, HOUR_TICK);
    for (int j = 1; j <= 4; j++) draw_tick(i*5 + j, MINUTE_TICK);
  }
  draw_hand(current_time.get_minutes(), MINUTE_HAND);
  draw_hand((current_time.get_hours() +
  current_time.get_minutes()/60.0)*5, HOUR_HAND);
}

class WorldClock : public Clock {
public:
   WorldClock() {}
   WorldClock(string city_name, double hour_diff, Point center, double radius);
   void draw() const { Clock::draw(); cwin << city; }
private:
   Message city;
};

WorldClock::WorldClock(string city_name, double hour_diff, Point center, double radius) : Clock(center, radius)
{ Point p = center;
  p.move(0, -radius);
  city = Message(p, city_name);
  Time now;
  const double SECONDS_PER_HOUR = 60 * 60;
  now.add_seconds(hour_diff * SECONDS_PER_HOUR);
  set_time(now);
}

int main()
{ vector<WorldClock> clocks(6);

  clocks[0] = WorldClock("San Jose", 16, Point(-6.5, 5), 3);
  clocks[1] = WorldClock("Taipei", 7, Point(0, 5), 3);
  clocks[2] = WorldClock("Berlin", 1, Point(6.5, 5), 3);
  clocks[3] = WorldClock("Cairo", 2, Point(-6.5, -5), 3);
  clocks[4] = WorldClock("New York", 19, Point(0, -5), 3);
  clocks[5] = WorldClock("Bombay", 4.5, Point(6.5, -5), 3);

  for (int i = 0; i < clocks.size(); i++) clocks[i].draw();
  return 0;
}