Object Pascal

Материал из Википедии — свободной энциклопедии
Перейти к: навигация, поиск
Object Pascal
Семантика:

императивная

Класс языка:

мультипарадигмальный:
императивный, структурный, объектно-ориентированный, обобщённый[1], процедурный

Тип исполнения:

компилируемый

Появился в:

1986

Автор(ы):

Ларри Теслер, Никлаус Вирт

Расширение файлов:

.p, .pp, .pas

Система типов:

статическая, динамическая (array of const, RTTI, Variant), строгая

Основные реализации:

Delphi (x86 and CLI), Oxygene (CLI), Free Pascal (x86, x86-64, PowerPC, ppc64, SPARC and ARM), Virtual Pascal (x86), TMT Pascal (x86), Turbo51 (Intel 8051)

Диалекты:

Apple, Turbo Pascal, objfpc, Delphi, Delphi.NET, Oxygene

Испытал влияние:

Паскаль, Smalltalk

Повлиял на:

C#, Java

Object Pascal (англ. Объектный Паскаль) — язык программирования, разработанный в фирме Apple Computer в 1986 году группой Ларри Теслера, который консультировался с Никлаусом Виртом. Произошёл от более ранней объектно-ориентированной версии Паскаль[2], называвшейся Clascal, который был доступен на компьютере Apple Lisa.

Изменения в Object Pascal от Borland в сравнении с Turbo Pascal[править | править вики-текст]

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

  • Фундаментальные (fundamental) типы. Их представление в памяти (число битов и наличие знака) строго фиксируется и выдерживается неизменным во всех последующих реализациях Object Pascal для любых операционных систем и компьютерных платформ.
  • Родовые (generic) типы. Их представление в памяти не фиксируется и будет реализовано оптимальным способом, в зависимости от реализации для конкретной операционной системы и компьютерной платформы.

Интерфейсы[править | править вики-текст]

См. Интерфейсы: Delphi

Перегрузка процедур и функций (не ООП)[править | править вики-текст]

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

procedure Calc(I: Integer); overload;
// ...
procedure Calc(S: String; J: Integer); overload;

Динамический массив[править | править вики-текст]

Введен для устранения рутинных операций выделения и возвращения памяти в heap-область (кучу), и для того, чтобы избежать случайных ошибок и утечки памяти. Элементы массива должны быть одинаковыми. Нумерация элементов начинается с нуля.

Пример объявления:

var MyFlexibleArray: array of Real;

Использование:

var
  A, B: array of Integer;
begin
  SetLength(A, 1); //специальная процедура выделения памяти
  A[0] := 1;
  B := A;
  B[0] := 2;
end;

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

type TDynamicCharArray = array of Char;
function Find(A: TDynamicCharArray): Integer;

Динамическая типизация[править | править вики-текст]

Операторы динамической проверки и приведения типов[править | править вики-текст]

В языке Object Pascal фирмы Borland появилась динамическая типизация, а также оператор динамического приведения типов as и оператор is для динамической проверки типов. Также в открытом массиве параметров стала возможна передача параметров различного типа (variant open array parameters).

Вариантный тип[править | править вики-текст]

В языке Object Pascal был введен вариантный тип данных (Variant), тип которых не известен на этапе компиляции и может изменяться на этапе выполнения программы. Однако этот тип данных поглощает больше памяти по сравнению с соответствующими переменными и операции над данными типа Variant выполняются медленнее. Более того, недопустимые операции над данными этого типа чаще приводят к ошибкам на этапе выполнения программы, в то время как подобные ошибки над данными другого типа были бы выявлены ещё на этапе компиляции.

Вариантные переменные могут принимать различные значения (целые, строковые, булевские, Currency, OLE-строки), быть массивами элементов этих же типов и массивом значений вариантного типа, а также содержать COM и CORBA объекты, чьи методы и свойства могут быть доступны посредством этого типа. Однако Variant не может содержать:

  • данные структурных типов;
  • указатели;
  • Int64 (начиная с Delphi 6 — может).

Variant можно смешивать (в выражениях и операторах) с другими вариантами, числовыми, строковыми и булевскими данными. При этом компилятор автоматически выполняет преобразование типа. Варианты, содержащие строки, не могут, однако, индексироваться (V[i] не допустимо).

var
  V1, V2, V3, V4, V5: Variant;
  I: Integer;
  D: Double;
  S: String;
begin
  V1 := 1; //значение типа integer
  V2 := 359.768; //значение типа real
  V3 := 'Hello world!'; //значение типа string
end;

Параметры типа вариантного открытого массива[править | править вики-текст]

Стала возможна передача параметров различного типа. В оригинале он назван как «variant open array parameters». Тип данных определяется динамически в процессе выполнения программы. Так же как и в обычном открытом массиве функция High вызывается для определения числа элементов массива. Для объявления используются ключевые слова array of const. Пример:

function Output(const Args: array of const): string;
var
  I: Integer;
begin
  Result := '';
  for I := 0 to High(Args) do with Args[I] do
    case VType of
      vtString:     Result := Result + VString^;
      vtPChar:      Result := Result + VPChar;
      vtInteger:    Result := Result + IntToStr(VInteger);
      vtBoolean:    Result := Result + BoolToStr(VBoolean);
      vtChar:       Result := Result + VChar;
      vtExtended:   Result := Result + FloatToStr(VExtended^);
      vtObject:     Result := Result + VObject.ClassName;
      vtClass:      Result := Result + VClass.ClassName;
      vtVariant:    Result := Result + string(VVariant^);
      vtInt64:      Result := Result + IntToStr(VInt64^);
      vtAnsiString: Result := Result + string(VAnsiString);
      vtCurrency:   Result := Result + CurrToStr(VCurrency^);
    end;
 
  Result := Result + ' ';
end;
//...
 
Output(['test', 777, '@', True, 3.14159, TForm]); //передача открытого массива параметров

Будет возвращена строка: «test 777 @ T 3.14159 TForm».

Как видно, имеет свою внутреннюю структуру, обращение к которой дает возможность определить тип данных. В строке вызова функции создается массив, с помощью конструктора открытого массива, который использует квадратные скобки.

Различия в объектных моделях[править | править вики-текст]

Для введения новой объектной модели введено ключевое слово classTurbo Pascal ключевое слово object).

Введены операторы для проверки и приведения классов is и as динамически в ходе выполнения программы. Появились указатели на методы, для чего введено новое использование ключевого слова object:

type
  TMyMethod = procedure (Sender : Object) of object;

Изменения синтаксиса, из-за изменения размещения объектов[править | править вики-текст]

В Turbo Pascal можно было работать как с динамическими, так и со статическими экземплярами объектов.

В объектной модели Object Pascal программист работает только с динамическими экземплярами классов, выделяемых в heap-области (куче). В связи с этим изменен синтаксис обращения к полям и методам объектов.

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

Пример для сравнения:

Объектная модель в Turbo Pascal:

type
  PMyObject = ^TMyObject;
  TMyObject = object (TObject)
    MyField : PMyType;
    constructor Init;
  end;
//...
var
  MyObject : PMyObject;
begin
  MyObject := New(PMyObject,Init);
  MyObject^.MyField := //...
end;

Новая объектная модель в Object Pascal:

type
  TMyObject = class (TObject)
    MyField : TMyType;
    constructor Create;
  end;
//...
var
  MyObject : TMyObject;
begin
  MyObject := TMyObject.Create;
  MyObject.MyField := //...
end;

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

Появилась возможность ограничивать видимость членов класса (методы, свойства), которые предназначены для использования только в реализации производных классов. Это дает возможность защищать исходный код от модификации пользователями класса. Такие методы содержатся в секции protected (защищённые) в объявлении класса.

Визуальное объектно-ориентированное программирование[править | править вики-текст]

Появились понятия свойства (property) и связанные с со свойствами ключевые слова read, write, stored, default (nodefault), index. Свойства визуальных объектов, видимых в интегрированной среде разработки объявляются с помощью нового слова published в качестве секции в объявлении класса, являющегося визуальным объектом.

Обобщения[править | править вики-текст]

type
  {объявление}
  generic TList<T> = class
    Items: array of T;
    procedure Add(Value: T);
  end;
 
implementation
  {реализация}
  procedure TList.Add(Value: T);
  begin
    SetLength(Items, Length(Items) + 1);
    Items[Length(Items) - 1] := Value;
  end;

Общий класс может быть просто специализирован для конкретного типа с использованием ключевого слова specialize:

type
  TIntegerList = specialize TList<Integer>;
  TPointerList = specialize TList<Pointer>;
  TStringList  = specialize TList<string>;

Перегрузка операторов[править | править вики-текст]

Разработчики TMT Pascal (модификация Object Pascal) первыми ввели полноценную перегрузку операторов, что впоследствии было перенято разработчиками других диалектов языка: Delphi (с Delphi 2005), Free Pascal и др.

Пример:

{объявление}
type
  TVector = packed record
    A, B, C: Double;
    procedure From(const A, B, C: Double);
    class operator Add(const Left, Right: TVector): TVector;
    class operator Implicit(const v: TVector): TPoint;
  end;
 
{реализация}
implementation
//...
  class operator TVector.Add(const Left, Right: TVector): TVector;
  begin
    Result.A := Left.A + Right.A;
    Result.B := Left.B + Right.B;
    Result.C := Left.C + Right.C;
  end;
 
  class operator TVector.Implicit(const v: TVector): TPoint;
  begin
    Result.A := round(v.A);
    Result.B := round(v.B);
  end;
//...
 
{использование}
var
  v1, v2: TVector;
begin
  v1.From(20, 70, 0);
  v2.From(15, 40, 4);
  Canvas.Polygon([v1, v2, v1 + v2]);
end;

Поддержка различными разработчиками[править | править вики-текст]

Начиная с версии среды Delphi 7, фирма Borland стала официально называть язык Object Pascal как Delphi[3].

Язык Object Pascal поддерживается и развивается другими разработчиками. Наиболее серьёзные реализации Object Pascal (помимо Delphi) — это кроссплатформенный TopSpeed Pascal (версия языка Turbo Pascal[4]) мультиязыковой среды TopSpeed, TMT Pascal, Virtual Pascal, PascalABC.NET, Free Pascal, GNU Pascal. На Object Pascal основан язык программирования Oxygene.

Примеры «Hello, world!» в различных объектных расширениях языка[править | править вики-текст]

Примечания[править | править вики-текст]

  1. Hallvard’s Blog: Highlander2 Beta: Generics in Delphi for .NET
  2. Буч Г. Объектно-ориентированное проектирование с примерами решения[itbookz.ifolder.ru/7276278]
  3. Delphi Language Overview
  4. TopSpeed-компиляторы: не дожили до триумфа
  5. Michaël Van Canneyt. Chapter 6: Classes (англ.). Free Pascal : Reference guide. (декабрь 2011). Проверено 16 января 2012. Архивировано из первоисточника 2 февраля 2012.