Файл: 7. Взаимодействие классов на основе наследования.pdf

Добавлен: 20.10.2018

Просмотров: 1377

Скачиваний: 15

ВНИМАНИЕ! Если данный файл нарушает Ваши авторские права, то обязательно сообщите нам.
background image

 

 

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

включить  ряд  интересных  и  мощных  механизмов,  основанных  на  понятии 

полиморфизма.  В  последующих  разделах  эти  вопросы  будут  рассмотрены 

более подробно. 

Теперь можно привести формальное описание класса окружностей как 

производного от базового абстрактного класса фигур. 

TCircle = сlass (TFigure)   //  включаем механизм наследования! 

     рrivate                          // а можно - protected 

          r : integer;                // x, y    унаследованы и могут использоваться 

      public 

          constructor  Create (ax, ay, ar : integer); 

          procedure  SetRad (ar : integer);  //  остальные методы  унаследованы! 

          function  GetRad : integer;  

          procedure  Show;   //  надо реализовать 

          procedure  MoveTo (ax, ay : integer);  // и это надо 

end; 

       Фрагменты программной реализации: 

constructor  TCircle.Create (ax, ay, ar : integer); 

   begin 

      inherited   Create (ax, ay);      r := ar; 

   end; 

procedure  TCircle.MoveTo (ax, ay : integer);   

   begin 

      Show;   

      SetXY(GetX+ax, GetY+ay);    // если координаты закрыты 

     // или так:     x := x+ax;   y := y+ay;   если они  protected 

      Show; 

   end; 

 


background image

 

 

сlass   Circle  extends  Figure   {   //  включаем механизм наследования! 

     рrivate   int   r;                    // а можно - protected 

     public     Circle (int  ax, int  ay, int  ar) { super (ax, ay);  r = ar;} 

     public     void   SetRad (int   ar) {…};  //  остальные методы  унаследованы! 

     public     int   GetRad( ) {…;}  

     public     void   Show( ) {…;}   //  надо реализовать 

     public     void   MoveTo (int  ax, int  ay)  // и это надо 

         { Show( );  SetXY(GetX+ax, GetY+ay);     

                   // или так:     x = x+ax;   y = y+ay;   если они  protected 

             Show( );  } 

};

 

 

Второй  дочерний  класс  –  это  класс  прямоугольников  со  следующей 

структурой: 

  два закрытых или защищенных поля для ширины и высоты (поля для 

координат центра будут наследоваться из базового класса фигур) 

  конструктор для создания прямоугольника 

  методы  доступа  к  ширине  и  высоте  (методы  доступа  к  координатам 

будут наследоваться) 

  реальные  методы  отображения  (Show,  однако!)  и  перемещения 

(конечно же  - MoveTo) прямоугольников 

TRect = сlass (TFigure)   //  включаем механизм наследования! 

     рrivate    //   или   protected 

          h, w : integer;   // x, y   унаследованы и могут использоваться 

      public 

          constructor  Create (ax, ay, ah, aw : integer); 

          procedure  SetHW (ah, aw : integer);  //  остальные  унаследованы! 

          function  GetH : integer;  

          function  GetW : integer;  

          procedure  Show; 


background image

 

 

          procedure  MoveTo (ax, ay : integer); 

end; 

   //  реализация методов 

 

сlass   Rect   extends  Figure  {   //  включаем механизм наследования! 

     рrivate    int   h, w;    //   или   protected 

     public   Rect(int  ax, int  ay, int  ah, int  aw) { super(ax, ay); h = ah; w = aw;} 

     public   void   SetHW (int  ah, int  aw);  //  остальные  унаследованы! 

     public   int   GetH( ) {…;}  

     public   int   GetW( ) {…;}  

     public   void   Show( ) {…;} 

     public   void   MoveTo (int  ax, int  ay) {…;} 

};

 

 

Н  основе  класса  окружностей  можно  построить  свои  производные 

классы, например – класс эллипсов и класс дуг. Для класса эллипсов к трем 

полям данных надо добавить еще одно – для вертикальной полуоси (радиус 

надо  теперь  трактовать  как  горизонтальную  полуось).  Можно  добавить  и 

новый метод – поворот эллипса на 90 градусов (для окружности этот метод 

не  имеет  смысла).  Введение  нового  свойства  и  нового  метода  показывает 

возможность  расширения  родительского  класса  с  одновременным 

использованием  всех  ранее  реализованных  методов.  В  сокращенной  форме 

класс эллипсов можно описать следующим образом: 

TEllipse = сlass (TCircle)   // включаем наследование 

     рrivate   // объявляем только одно свойство 

          r2 : integer;   // x, y  и  r  наследуются 

      public 

 

constructor  Create (ax, ay, ar, ar2 : integer); 

         // методы доступа к  r2  

         procedure  Show;   // имя – одинаковое во всей иерархии! 


background image

 

 

         procedure  MoveTo (ax, ay : integer); // аналогично 

         procedure  Rotate90;   // новый метод 

   end

   //  программная реализация методов 

 

сlass   Ellipse   extends  Circle          // включаем наследование  

 {   рrivate  int    r2;   // x, y  и  r  наследуются 

      public  Ellipse (int  ax, int  ay, int  ar, int  ar2) {…;} 

         // методы доступа к  r2  

      public   void  Show( ) {…;}   // имя – одинаковое во всей иерархии! 

      public   void  MoveTo (int  ax, int  ay) {…;} // аналогично 

      public   void  Rotate90( ) {…;}   // новый метод 

  };

 

 

Этот класс можно сравнить с аналогичным, но созданным «с нуля», т.е. 

без  использования  наследования  и  родительских  классов.  Такой  класс 

содержал  бы  4  свойства  и  8  методов  доступа.  Даже  на  таком  простом 

примере можно увидеть преимущества механизма наследования. 

Ну  а  как  на  основе  класса  окружностей  построить  класс  дуг?  Очень 

просто  –  надо  добавить  лишь  два  новых  поля  данных  для  значений  двух 

углов! Все остальное (координаты центра, радиус) уже есть. 

TArc = сlass (TCircle)    

     private 

          a1, a2 : integer;   // x, y  и  r  наследуются 

      public 

 

// конструктор, методы доступа к а1 и а2, методы Show и MoveTo 

 

procedure  Rotate (angle : integer);  // новый метод поворота 

   end

 

сlass   Arc  extends   Circle    


background image

 

 

 {   private   int   a1, a2;   // x, y  и  r  наследуются 

      public 

 

// конструктор, методы доступа к а1 и а2, методы Show и MoveTo 

      public   void   Rotate (int   angle) {…;}  // новый метод поворота дуги 

 };

 

 

В  свою  очередь,  на  основе  класса  прямоугольников  можно  создать 

такие  производные  классы  как  класс  повернутых  прямоугольников 

(добавляется  новое  поле  данных  –  угол  поворота)  и  класс  закрашенных 

прямоугольников (добавляется новое поле – цвет закраски). 

TRotateRect = сlass (TRect) 

     private 

          angle : integer;   // x, y, h, w  унаследованы и могут использоваться 

      public 

 

//  конструктор, методы доступа к углу, методы Show и  MoveTo 

         procedure  Rotate (ang : integer); // новый метод поворота прям-ника 

   end

 

сlass   RotateRect   extends   Rect 

 {   private   int   angle;   // x, y, h, w  унаследованы и могут использоваться 

      public 

 

//  конструктор, методы доступа к углу, методы Show и  MoveTo 

      public  void  Rotate (int  ang) {…;} // новый метод поворота прям-ника 

  };

 

 

Замечание. Рассмотренный вариант иерархии графических объектов не 

является  окончательным  –  его  можно  улучшить,  сделать  более 

универсальным,  но  только  после  изучения  механизмов,  основанных  на 

принципе полиморфизма.