Borland Pascal. Руководство пользователя
6cac1dc9

Совместимость типов объектов


Наследование до некоторой степени изменяет правила совмести- мости типов в Borland Pascal. Помимо всего прочего, порожденный тип наследует совместимость типов всех своих порождающих типов. Эта расширенная совместимость типов принимает три формы:

- между реализациями объектов; - между указателями на реализации объектов; - между формальными и фактическими параметрами.

Однако очень важно помнить, что во всех трех формах совмес- тимость типов расширяется только от потомка к родителю. Другими словами, дочерние типы могут свободно использоваться вместо роди- тельских, но не наоборот.

В модуле WORKERS.TPU TSalaried является потомком TEmployee, а TCommissioned - потомком TSalaried. Помня об этом, рассмотрим следующие описания:

tyрe PEmрloyee = ^TEmployee; PSalaried = ^TSalfried; PCommissioned = ^TCommissioned; var AnEmрloyee: TEmployee; ASalaried: TSalaried; PCommissioned: TCommissioned; TEmployeePtr: PEmрloyee; TSalariedPtr: PSalaried; TCommissionedPtr: PCommissioned;

При данных описаниях справедливы следующие операторы присва- ивания:

AnEmрloyee :=ASalaried; ASalaried := ACommissioned; TCommissionedPtr := ACommissioned;

Примечание: Порождающему объекту можно присвоить эк- земпляр любого из его порожденных типов.

Обратные присваивания недопустимы.

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

В операторах присваивания из источника в приемник будут ко- пироваться только поля, являющиеся общими для обоих типов. В опе- раторе присваивания:


AnEmрloyee := ACommissioned;

Только поля Name, Title и Rate из ACommissioned будут скопи- рованы в AnEmрloyee, т.к. только эти поля являются общими для TCommissioned и TEmployee. Совместимость типов работает также между указателями на типы объектов и подчиняется тем же общим правилам, что и для реализаций объектов. Указатель на потомка мо- жет быть присвоен указателю на родителя. Если дать предыдущие оп- ределения, то следующие присваивания указателей будут допустимы- ми:

TSalariedPtr := TCommissionedPtr; TEmployeePtr := TSalariedPtr; TEmployeePtr := PCommissionedPtr;

Помните, что обратные присваивания недопустимы.

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

рrocedure CalcFedTax(Victim: TSalaried);

то допустимыми типами фактических параметров могут быть TSalaried или TCommissioned, но не тип TEmployee. Victim также может быть параметром-переменной. При этом выполняются те же правила совмес- тимости.

Замечание: Имейте в виду, что между параметрами-значениями и параметрами-переменными есть коренное отличие. Параметр-значение является указателем на действительный, посылаемый в качестве па- раметра объект, тогда как параметр-переменная является только ко- пией фактического параметра. Более того, эта копия включает толь- ко те поля, которые входят в тип формального параметра-значения. Это означает, что фактический параметр буквально преобразуется к типу формального параметра. Параметр-переменная больше напоминает приведение к образцу, в том смысле, что фактический параметр ос- тается неизменным.

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

рrocedure Worker.Add (AWorker: PSalaried);

тогда допустимыми типами фактических параметров могут быть PSalaried или PCommissioned, но не тип PEmрloyee.


Содержание раздела