Шаг 130.
Сравнение объектов старой и новой ООП-моделей

    На этом шаге мы рассмотрим различия старой и новой ООП-модели.


    Одно из существенных отличий новой ООП-модели от старой состоит в том, что теперь все объекты, как стандартные, так и описанные пользователем, являются динамическими (не путать с виртуальными и динамическими методами!). Статических объектов в Object Pascal нет.

    Из этого вытекает несколько следствий:

  1. Все объекты, то есть переменные классовых типов, фактически являются указателями.
  2. На этапе компиляции для всех объектов, независимо от их класса, выделяются одинаковые области памяти только для хранения адреса объекта. Для самого же экземпляра класса на этапе компиляции память не выделяется.

    Следовательно, прежде чем обращаться к полям, методам и свойствам конкретного объекта, разработчик сначала должен в коде своего проекта создать этот объект (т.е. распределить память и инициализировать) с помощью вызова конструктора того класса, к которому принадлежит объект.

    Поскольку больше нет необходимости синтаксически различать статические и динамические объекты, синтаксис описания и работы с объектами в новой ООП-модели был несколько упрощен.

    Чтобы показать синтаксические особенности для сравнения приведем одинаковые фрагменты, записанные по старой и новой ООП-модели.

    Старая ООП-модель:

program OldModel; 
uses WinCrt;
type
  PMyDynObjType = ^TMyDynObjType; 
  TMyDynObjType = object 
      Field : Integer;
      constructor Init (Value : Integer); 
  end;
const
  n = 5; 
var
  MyDynObj : array [1..n] of PMyDynObjType;
  i : Integer;

constructor TMyDynObjType.Init;
begin
  Field := Value 
end;

begin
  ClrScr;
  New (MyDynObj[1], Init(1));
  for i := 2 to n do
    New (MyDynObj[i], Init(i)); 
  for i := 1   to n  do
    Writeln   (MyDynObj[i]^.Field) 
end.

    Новая ООП-модель:

program NewModel;
{uses Forms;} 
type
  TMyDynObjClass = class 
    Field : Integer;
    constructor Create (Value : Integer); 
  end;
const
  n = 5; 
var
  MyDynObj : array [1..n] of TMyDynObjClass;
  i : Integer;

constructor TMyDynObjClass.Create; 
begin
  Field := Value 
end;

begin
  MyDynObj[1] := TMyDynObjСlass.Create(1); 
  for i := 2 to n do
    MyDynObj[i] : = TMyDynObjClass.Create(i); 
  for i := 1 to n do
    Writeln (MyDynObj[i].Field); 
  Readln; 
end.

    Пример новой ООП-модели для большей корректности сравнения подготовлен для работы в консольном режиме.

    Синтаксические отличия, как видно из примеров, заключаются в том, что теперь нет необходимости описывать указатели на класс и использовать операцию разыменования (^), которые подразумеваются по умолчанию, а также вызывать процедуру New для создания объекта и процедуру Dispose для удаления объекта.


    Поскольку все описанные классы являются потомками TObject, то выделение памяти для объектов теперь является стандартным действием конструктора Create, а освобождение памяти - стандартным действием деструктора Destroy.

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

    Поскольку, как отмечалось выше, Object Pascal поддерживает обе ООП-модели, и старую, и новую, то пример для старой ООП-модели также будет работать и в Delphi. Но, если в 16-разрядной версии Delphi этот пример работает точно в таком же виде, то, начиная с Delphi 2.0, модуль WinCrt не поддерживается. Поэтому для запуска примера в консольном режиме приложения нужно будет удалить ссылку на модуль WinCrt и вызов объявленной в нем процедуры ClrScr, а также добавить вызов Readln перед последним end для задержки окна консоли на экране монитора.

    На следующем шаге мы поговорим о конструкторах.




Предыдущий шаг Содержание Следующий шаг