Наследование до некоторой степени изменяет правила совмести-
мости типов в 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.