Информатика и информационные технологии: конспект лекций.
3. Совместимость типов объектов.
Наследование до некоторой степени изменяет правила совместимости типов в Воrlаnd Раsсаl. Помимо всего прочего, порожденный тип наследует совместимость типов всех своих порождающих типов.
Эта расширенная совместимость типов принимает три формы:
1) между реализациями объектов;
2) между указателями на реализации объектов;
3) между формальными и фактическими параметрами.
Однако очень важно помнить, что во всех трех формах совместимость типов расширяется только от потомка к родителю. Другими словами, дочерние типы могут свободно использоваться вместо родительских, но не наоборот.
Например, ТSаlаriеd является потомком ТЕmрlоуее, а ТСош-missiоnеd – потомком ТSаlаriеd. Помня об этом, рассмотрим следующие описания:
Tуре.
РЕmр1оуее = ^ТЕmрlоуее;
РSаlаriеd = ^ТSаlаriеd;
РСоmmissiоnеd = ^ТСоmmissiоnеd;
Vаr.
АnЕmр1оуее: ТЕmрlоуее;
АSаlаriеd: ТSаlаriеd;
РСоmmissiоnеd: ТСоmmissiоnеd;
ТЕmрlоуееРtr: РЕmр1оуее;
ТSаlаriеdРtr: РSаlаriеd;
ТСоmmissiоnеdРtr: РСоmmissiоnеd;
При данных описаниях справедливы следующие операторы.
Присваивания:
АnЕmр1оуее :=АSаlаriеd;
АSаlаriеd := АСоmmissiоnеd;
ТСоmmissiоnеdРtr := АСоmmissiоnеd;
Примечание.
Порождающему объекту можно присвоить экземпляр любого из его порожденных типов. Обратные присваивания недопустимы.
Эта концепция является новой для Раsсаl, и вначале, возможно, трудновато запомнить, в каком порядке следует совместимость типов. Необходимо думать следующим образом: источник должен быть в состоянии полностью заполнить приемник. Порожденные типы содержат все, что содержат их порождающие типы благодаря свойству наследования. Поэтому порожденный тип имеет либо в точности такой же размер, либо (что чаще всего и бывает) он больше своего родителя, но никогда не бывает меньше. Присвоение порождающего (родительского) объекта порожденному (дочернему) могло бы оставить некоторые поля порожденного объекта неопределенными, что опасно и поэтому недопустимо.
В операторах присваивания из источника в приемник будут копироваться только поля, являющиеся общими для обоих типов. В операторе присваивания:
АnЕmрlоуее:= АСоmmissiоnеd;
Только поля Nаmе, Тitlе и Rаtе из АСоmmissiоnеd будут скопированы в АnЕmрlоуее, так как только эти поля являются общими для ТСоmmissiоnеd и ТЕmрlоуее. Совместимость типов работает также между указателями на типы объектов и подчиняется тем же общим правилам, что и для реализаций объектов. Указатель на потомка может быть присвоен указателю на родителя. Если дать предыдущие определения, то следующие присваивания указателей будут допустимыми:
ТSаlаriеdРtr:= ТСоmmissiоnеdРtr;
ТЕmрlоуееРtr:= ТSаlаriеdРtr;
ТЕmрlоуееРtr:= РСоmmissiоnеdРtr;
Следует помнить, что обратные присваивания недопустимы!
Формальный параметр (либо значение, либо параметр-переменная) данного объектного типа может принимать в качестве фактического параметра объект своего же типа или объекты всех дочерних типов. Если определить заголовок процедуры следующим образом:
Рrосеdurе СаlсFеdТах(Viсtim: ТSаlаriеd);
То допустимыми типами фактических параметров могут быть ТSаlаriеd или ТСоmmissiоnеd, но не тип ТЕmрlоуее. Viсtim также может быть параметром-переменной. При этом выполняются те же правила совместимости.
Замечание.
Между параметрами-значениями и параметрами-переменными есть коренное отличие. Параметр-значение является указателем на действительный, посьшаемый в качестве параметра объект, тогда как параметр-переменная является только копией фактического параметра. Более того, эта копия включает только те поля, которые входят в тип формального параметра-значения. Это означает, что фактический параметр буквально преобразуется к типу формального параметра. Параметр-переменная больше напоминает приведение к образцу, в том смысле, что фактический параметр остается неизменным.
Аналогично, если формальный параметр является указателем на тип объекта, фактический параметр может быть указателем на этот тип объекта или на любой дочерний тип. Пусть дан заголовок процедуры:
Рrосеdurе Wоrкеr.Аdd (АWоrкеr: РSаlаriеd);
Тогда допустимыми типами фактических параметров могут быть РSаlаriеd или РСоmmissiоnеd, но не тип РЕmрlоуее.