Object Pascal
Object Pascal (с англ. — «Объектный Паскаль») — язык программирования, разработанный в фирме Apple Computer в 1986 году группой Ларри Теслера, который консультировался с Никлаусом Виртом[1]. Произошёл от более ранней объектно-ориентированной версии Паскаль[2], называвшейся Clascal, который был доступен на компьютере Apple Lisa. Изменения в Object Pascal от Borland в сравнении с Turbo PascalИзменения коснулись групп целых, символьных и строковых типов, которые стали разделяться на две категории:
ИнтерфейсыПерегрузка процедур и функций (не ООП)Введена перегрузка процедур и функций, не являющихся членами объекта или класса. Перегружаются (с помощью ключевого слова 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;
Начиная с Delphi XE7 стали возможны следующие действия с динамическими массивами: var M: array of integer;
begin
M := [1, 2, 3, 4, 5];
end;
M := M + [5, 6, 7];
Insert([6, 7, 8], M, 5); // вставка массива [6, 7, 8], в M, начиная с индекса 5
Delete(M, 1, 3); // удаляем 3 элемента, начиная с индекса 1
Concat([1, 2, 3, 4], [5, 6, 7])
То есть с динамическими массивами можно работать так же, как со строками. В динамическом массиве также возможно задание открытого массива параметров, но тип их должен быть объявлен ранее, например: 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 не может содержать:
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». Как видно, имеет свою внутреннюю структуру, обращение к которой даёт возможность определить тип данных. В строке вызова функции создаётся массив, с помощью конструктора открытого массива, который использует квадратные скобки. Различия в объектных моделяхДля введения новой объектной модели введено ключевое слово class (в Turbo 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. Начиная с версии Delphi XE появились статические методы класса.[3] Появилась возможность ограничивать видимость членов класса (методы, свойства), которые предназначены для использования только в реализации производных классов. Это даёт возможность защищать исходный код от модификации пользователями класса. Такие методы содержатся в секции 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[4]. Язык Object Pascal поддерживается и развивается другими разработчиками. Наиболее серьёзные реализации Object Pascal (помимо Delphi) — это кроссплатформенный TopSpeed Pascal (версия языка Turbo Pascal[5]) мультиязыковой среды TopSpeed, TMT Pascal, Virtual Pascal, PascalABC.NET, Free Pascal, GNU Pascal. Язык программирования Oxygene является диалектом Object Pascal для платформы .NET и дальнейшим его развитием, а новыми возможностями языка является оператор ":", асинхронный и отложенный вызовы методов, асинхронное выполнение блока кода, параллельные циклы, анонимные конструкторы, элементы контрактного и аспектно-ориентированного программирования и др.[6] (компилятор распространяется без ограничений). Примеры «Hello, world!» в различных объектных расширениях языкаObject Pascal от Apple program ObjectPascalExample;
type
THelloWorld = object
procedure Put;
end;
var
HelloWorld: THelloWorld;
procedure THelloWorld.Put;
begin
WriteLn('Hello, World!');
end;
begin
New(HelloWorld);
HelloWorld.Put;
Dispose(HelloWorld);
end.
Turbo Pascal Delphi (для обеспечения обратной совместимости) и Free Pascal также поддерживают этот вариант синтаксиса. program ObjectPascalExample;
type
PHelloWorld = ^THelloWorld;
THelloWorld = object
procedure Put;
end;
var
HelloWorld: PHelloWorld; { это указатель на THelloWorld }
procedure THelloWorld.Put;
begin
WriteLn('Hello, World!');
end;
begin
New(HelloWorld);
HelloWorld^.Put;
Dispose(HelloWorld);
end.
Delphi и Free Pascal В Free Pascal этот вариант синтаксиса доступен в режимах ObjFpc и Delphi.[7] program ObjectPascalExample;
type
THelloWorld = class { определение класса }
procedure Put;
end;
procedure THelloWorld.Put; { описание процедуры метода Put класса THelloWorld }
begin
Writeln('Hello, World!');
end;
var
HelloWorld: THelloWorld; { определение переменной-указателя на экземпляр класса }
begin
HelloWorld := THelloWorld.Create; { конструктор возвращает значение указателя на экземпляр класса }
HelloWorld.Put;
HelloWorld.Free; { деструктор уничтожает экземпляр класса и освобождает область памяти }
end.
Примечания
|
Portal di Ensiklopedia Dunia