PASCAL ABC Виртуальные методы и полиморфизм

  • docx
  • 11.11.2021
Публикация на сайте для учителей

Публикация педагогических разработок

Бесплатное участие. Свидетельство автора сразу.
Мгновенные 10 документов в портфолио.

Иконка файла материала Л2-00391.docx

PASCAL ABC

Виртуальные методы и полиморфизм

Пусть переопределенный в подклассе метод базового класса имеет тот же список формальных параметров (а для функций - и тип возвращаемого значения). Например:

type
  Base=class
    procedure Print;
    begin
      writeln('Base');
    end;
  end;
  Derived=class(Base)
    procedure Print;
    begin
      writeln('Derived');
    end;
  end;

Рассмотрим различные способы вызова метода Print:

var
  b,b1: Base;
  d: Student;
  ...
  b:=Base.Create;
  d:=Derived.Create;
  b1:=d;
  b.Print; //
вызывается Base.Print
  d.Print; //
вызывается Derived.Print
  b1.Print;

Какая версия метода Print вызывается в последнем случае - класса Base или класса Derived? В объектно-ориентированных языках программирования возможны две ситуации. Если решение о том, какой метод вызывать, принимается на этапе компиляции на основании типа, заявленного при описании b1, то вызывается метод Base.Print (говорят также, что имеет место раннее связывание имени метода с его телом). Если же решение о том, какой метод вызывать, принимается на этапе выполнения программы в зависимости от реального типа объекта, на который ссылается переменная b1, то вызывается метод Derived.Print (говорят также, что имеет место позднее связывание). Методы, для которых реализуется позднее связывание, называются виртуальными, а способность объекта вызывать через переменную базового класса метод производного класса на основании информации во время выполнения программы называется полиморфизмом.

В языке Pascal ABC все методы (за исключением конструкторов) являются виртуальными, т.е. в последнем случае вызовется функция Derived.Print.

Полиморфизм (англ.: много форм) используется в ситуации, когда для группы взаимосвязанных объектов требуется выполнить единое действие, но каждый из этих объектов должен выполнить указанное действие по-своему (т.е. у действия возникает много форм). Для этого определяется базовый для всех объектов класс с методом, предусмотренным для выполнения указанного действия, после чего этот метод переопределяется во всех потомках. Например:

type
  Shape=class
    procedure Draw; begin end;
  end;
  Point=class
    procedure Draw; begin ... end;
  end;
  Rectangle=class
    procedure Draw; begin ... end;
  end;
  Circle=class
    procedure Draw; begin ... end;
  end;
var a: array[1..4] of Shape;
...
  a[1]:=Point.Create;
  a[2]:=Rectangle.Create;
  a[3]:=Point.Create;
  a[4]:=Circle.Create;
  for i:=1 to 4 do
    a[i].Draw;

В данном случае в качестве единого действия выступает метод Draw, но каждый объект выполняет его по-своему, обеспечивая полиморфное поведение. Говорят, что методы Draw в базовом классе Shape и его потомках образуют цепочку виртуальности.

Внимание! Если переопределяется private-метод, то цепочка виртуальности ломается, т.е. метод рассматривается как первый с этим именем в новой цепочке виртуальности.