Menu Home

Бесплатная техническая библиотека для любителей и профессионалов Бесплатная техническая библиотека


Информатика и информационные технологии. Ассемблер (конспект лекций)

Конспекты лекций, шпаргалки

Справочник / Конспекты лекций, шпаргалки

Комментарии к статье Комментарии к статье

Оглавление (развернуть)

ЛЕКЦИЯ № 13. Совместимость типов объектов

1. Инкапсуляция

Объединение в объекте кода и данных называется инкапсуляцией. В принципе, возможно предоставить достаточное количество методов, благодаря которым пользователь объекта никогда не будет обращаться к полям объекта непосредственно. Некоторые другие объектно-ориентированные языки, например Smalltalk, требуют обязательной инкапсуляции, однако в Borland Pascal имеется выбор.

Например, объекты TEmployee и THourly написаны таким образом, что совершенно исключена необходимость прямого обращения к их внутренним полям данных:

type

TEmployee = object

Name, Title: string[25];

Rate: Real;

procedure Init (AName, ATitle: string; ARate: Real);

function GetName : String;

function GetTitle : String;

function GetRate : Real;

function GetPayAmount : Real;

end;

THourly = object(TEmployee)

Time: Integer;

procedure Init(AName, ATitle: string; ARate:

Real, Atime: Integer);

function GetPayAmount : Real;

end;

Здесь присутствуют только четыре поля данных: Name, Title, Rate и Time. Методы GetName и GetTitle выводят фамилию работающего и его должность соответственно. Метод GetPayAmount использует Rate, а в случае работающего THourly и Time для вычисления суммы выплат работающему. Здесь уже нет необходимости обращаться непосредственно к этим полям данных.

Предположив существование экземпляра AnHourly типа THourly, мы могли бы использовать набор методов для манипулирования полями данных AnHourly например:

with AnHourly do

begin

Init (Aleksandr Petrov, Fork lift operator' 12.95, 62);

{Выводит на экран фамилию, должность и сумму выплат}

Show;

end;

Следует обратить внимание, что доступ к полям объекта осуществляется не иначе, как только с помощью методов этого объекта.

2. Расширяющиеся объекты

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

Определим дочерний по отношению к TEmployee тип, представляющий работника, которому платится часовая ставка, в следующем примере:

const

PayPeriods = 26; { периоды выплат }

OvertimeThreshold = 80; { на период выплаты }

OvertimeFactor = 1.5; { почасовой коэффициент }

type

THourly = object(TEmployee)

Time: Integer;

procedure Init(AName, ATitle: string; ARate:

Real, Atime: Integer);

function GetPayAmount : Real;

end;

procedure THourly.Init(AName, ATitle: string;

ARate: Real, Atime: Integer);

begin

TEmployee.Init(AName, ATitle, ARate);

Time := ATime;

end;

function THourly.GetPayAmount: Real;

var

Overtime: Integer;

begin

Overtime := Time - OvertimeThreshold;

if Overtime > 0 then

GetPayAmount := RoundPay(OvertimeThreshold * Rate +

Rate OverTime * OvertimeFactor * Rate)

else

GetPayAmount := RoundPay(Time * Rate)

end;

Человек, которому платится часовая ставка, является работающим: он обладает всем тем, что используется для определения объекта TEmployee (фамилией, должностью, ставкой), и лишь количество получаемых почасовиком денег зависит от того, сколько часов он отработал за период, подлежащий оплате. Таким образом, для THourly требуется еще и поле времени Time.

Так как THourly определяет новое поле Time, его инициализация требует нового метода Init, который инициализирует и время, и наследованные поля. Вместо того, чтобы непосредственно присвоить значения наследованным полям, таким как Name, Title и Rate, почему бы не использовать вновь метод инициализации объекта TEmployee (иллюстрируемый первым оператором THourly Init).

Вызов метода, который переопределяется, не является лучшим стилем. В общем случае возможно, что TEmployee.Init выполняет важную, однако скрытую инициализацию.

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

После вызова TEmployee.Init, THourly.Init может затем выполнить свою собственную инициализацию, которая в этом случае состоит только в присвоении значения, переданного в ATime.

Другим примером переопределяемого метода является функция THourly.GetPayAmount, вычисляющая сумму выплат работающему на почасовой ставке. В действительности, каждый тип объекта TEmployee имеет свой метод GetPayAmount, так как тип работающего зависит от того, как производится расчет. Метод THourly.GetPayAmount должен учитывать, сколько часов работал сотрудник, были ли сверхурочные работы, каков коэффициент увеличения за сверхурочные работы и т. д.

Метод TSalaried. GetPayAmount должен лишь делить ставку работающего на число выплат в каждом году (в нашем примере).

unit Workers;

interface

const

PayPeriods = 26; {в год}

OvertimeThreshold = 80; {за каждый период оплаты}

OvertimeFactor =1.5; {увеличение против обычной оплаты}

type

TEmployee = object

Name, Title: string[25];

Rate: Real;

procedure Init (AName, ATitle: string; ARate: Real);

function GetName : String;

function GetTitle : String;

function GetRate : Real;

function GetPayAmount : Real;

end;

THourly = object(TEmployee)

Time: Integer;

procedure Init(AName, ATitle: string; ARate:

Real, Atime: Integer);

function GetPayAmount : Real;

function GetTime : Real;

end;

TSalaried = object(TEmployee)

function GetPayAmount : Real;

end;

TCommissioned = object(TSalaried)

Commission : Real;

SalesAmount : Real;

constructor Init (AName, ATitle: String; ARate,

ACommission, ASalesAmount: Real);

function GetPayAmount : Real;

end;

implementation

function RoundPay(Wages: Real) : Real;

{округляем сумму выплат, чтобы игнорировать суммы меньше

денежной единицы}

begin

RoundPay := Trunc(Wages * 100) / 100;

.

.

.

TEmployee является вершиной нашей иерархии объектов и содержит первый метод GetPayAmount.

function TEmployee.GetPayAmount : Real;

begin

RunError(211); { дать ошибку этапа выполнения }

end;

Может вызвать удивление тот факт, что метод дает ошибку времени выполнения. Если вызывается Employee.GetPayAmount, то в программе возникает ошибка. Почему? Потому что TEmployee является вершиной нашей иерархии объектов и не определяет реального рабочего; следовательно, ни один из методов TEmployee не вызывается определенным образом, хотя они и могут быть наследованными. Все наши работники являются либо почасовиками, либо имеют оклады, либо работают на сдельщине. Ошибка на этапе выполнения прекращает выполнение программы и выводит 211, что соответствует сообщению об ошибке, связанной с вызовом абстрактного метода (если программа по ошибке вызывает TEmployee.GetPayAmount).

Ниже приводится метод THourly.GetPayAmount, в котором учитываются такие вещи, как сверхурочная оплата, число отработанных часов и т. д.

function THourly.GetPayAMount : Real;

var

OverTime: Integer;

begin

Overtime := Time - OvertimeThreshold;

if Overtime > 0 then

GetPayAmount := RoundPay(OvertimeThreshold * Rate +

Rate OverTime * OvertimeFactor * Rate)

else

GetPayAmount := RoundPay(Time * Rate)

end;

Метод TSalaried.GetPayAmount намного проще; в нем ставка

делится на число выплат:

function TSalaried.GetPayAmount : Real;

begin

GetPayAmount := RoundPay(Rate / PayPeriods);

end;

Если взглянуть на метод TCommissioned.GetPayAmount, то будет видно, что он вызывает TSalaried.GetPayAmount, вычисляет комиссионные и прибавляет их к величине, возвращаемой методом TSalaried. GetPayAmount.

function TСommissioned.GetPayAmount : Real;

begin

GetPayAmount := RoundPay(TSalaried.GetPayAmount +

Commission * SalesAmount);

end;

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

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

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

Эта расширенная совместимость типов принимает три формы:

1) между реализациями объектов;

2) между указателями на реализации объектов;

3) между формальными и фактическими параметрами.

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

Например, TSalaried является потомком TEmployee, а ТСош-missioned - потомком TSalaried. Помня об этом, рассмотрим следующие описания:

tyрe

PEmрloyee = ^TEmployee;

PSalaried = ^TSalaried;

PCommissioned = ^TCommissioned;

var

AnEmрloyee: TEmployee;

ASalaried: TSalaried;

PCommissioned: TCommissioned;

TEmployeePtr: PEmрloyee;

TSalariedPtr: PSalaried;

TCommissionedPtr: PCommissioned;

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

присваивания:

AnEmрloyee :=ASalaried;

ASalaried := ACommissioned;

TCommissionedPtr := ACommissioned;

Примечание

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

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

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

AnEmployee:= ACommissioned;

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

TSalariedPtr:= TCommissionedPtr;

TEmployeePtr:= TSalariedPtr;

TEmployeePtr:= PCommissionedPtr;

Следует помнить, что обратные присваивания недопустимы!

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

procedure CalcFedTax(Victim: TSalaried);

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

Замечание

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

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

procedure Worker.Add (AWorker: PSalaried);

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

Автор: Цветкова А.В.

<< Назад: Совместимость типов объектов (Инкапсуляция. Расширяющиеся объекты. Совместимость типов объектов)

>> Вперед: Регистры (Системные регистры микропроцессора. Регистры управления. Регистры системных адресов. Регистры отладки)

Рекомендуем интересные статьи раздела Конспекты лекций, шпаргалки:

▪ Метрология, стандартизация и сертификация. Шпаргалка

▪ Страховое право. Конспект лекций

▪ Инфекционные болезни. Конспект лекций

Смотрите другие статьи раздела Конспекты лекций, шпаргалки.

Читайте и пишите полезные комментарии к этой статье.

<< Назад

Последние новости науки и техники, новинки электроники:

Биокаталитический способ получения хиральных оксазолидинонов 14.10.2026

Химия все чаще обращается к биологическим молекулам, чтобы сделать синтез сложных веществ более точным и эффективным. Особенно важны такие технологии при создании соединений, у которых одинаковый химический состав может сопровождаться разным пространственным расположением атомов и, следовательно, различными свойствами. Исследователи из Калифорнийского технологического института и Университета Питтсбурга предложили новый биокаталитический подход, позволяющий получать хиральные оксазолидиноны непосредственно из простых неактивированных алкенов. В основе предложенного метода лежит последовательность из двух реакций - азиридинирования и последующего расширения цикла. Этот каскад запускается с помощью гемопротеина, который выполняет функцию катализатора и позволяет направлять химическое превращение в нужную сторону. В результате из относительно простого исходного соединения формируется более сложная циклическая структура с заданной пространственной конфигурацией. Особенно существенным ...>>

Клавиатура Gboard kurukuru version с вращающимися лентами 14.10.2026

Обычная клавиатура предполагает, что движется человек: пальцы перемещаются от одной неподвижной клавиши к другой, а расположение символов остается неизменным. Google Japan решила перевернуть этот привычный принцип и проверить, что произойдет, если заставить двигаться сам интерфейс. Так появился экспериментальный проект Gboard, в котором клавиши постоянно перемещаются и сами оказываются в зоне нажатия. Необычная конструкция получила название Gboard "Курукуру-версия" (Gboard kurukuru version). Проект стал очередным ежегодным экспериментом японского подразделения Google, посвященным альтернативным способам взаимодействия человека с текстом. На этот раз идея не ограничилась компьютерной концепцией: специалисты создали полноценный физический прототип, способный работать в реальных условиях, а материалы для его самостоятельного изготовления сделали доступными для всех желающих. Основу устройства образуют четыре замкнутые подвижные ленты, вращающиеся вокруг конструкции. На каждой из них ...>>

Легкий бег влияет на мозг и самоконтроль 13.10.2026

Физическая активность не обязательно должна быть интенсивной, чтобы на короткое время изменить состояние мозга. Новое исследование японских специалистов показывает, что даже непродолжительный бег с очень небольшой нагрузкой способен повлиять на настроение, внимание и способность контролировать собственные действия. Причем для этого, по данным эксперимента, может быть достаточно всего 10 минут. Работу провели исследователи из Университета Цукубы с участием 24 здоровых молодых людей. Добровольцы выполняли два разных условия: в одном случае они спокойно сидели в течение 10 минут, а в другом такое же время проводили на беговой дорожке. Скорость во время пробежки составляла приблизительно от 3 до 6 км/ч, поэтому нагрузка оставалась сравнительно небольшой. Средняя частота сердечных сокращений участников при этом находилась в пределах 104-107 ударов в минуту. После завершения физической активности добровольцы сообщали о большей бодрости и более приятном эмоциональном состоянии по сравне ...>>

Случайная новость из Архива

На мир надвигается дефицит гелия 21.09.2019

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

Начнем по порядку. Гелий - это инертный газ, который не имеет ни цвета, ни вкуса, ни запаха, и который гораздо легче воздуха, что и позволяет использовать его для наполнения шариков. Гелий не задерживается в земной атмосфере и не обладает собственными месторождениями - он добывается либо как побочный продукт из природного газа, либо извлекается при добыче других полезных ископаемых. До недавнего времени гелий добывался в основном на трех крупных площадках: одной в Катаре и двух в США (в Вайоминге и Техасе). Эти три источника обеспечивали около 75 процентов мирового производства гелия. Фактически, США десятилетиями были крупнейшим поставщиком гелия в мире, но теперь ситуация изменилась, так как запасы гелия в США критически истощились.

За последние 15 лет цена гелия выросла на 500 процентов, и в январе этого года ученые высказали предположение, что через 10 лет этого газа на Земле не останется вовсе. Еще в 2013 году был принят закон, по которому США уйдут с международного рынка гелия. На последнем аукционе, организованном властями США в сентябре прошлого года, где продавались квоты на поставки гелия в 2019 году, цена на этот газ выросла на 135 процентов в годовом отношении. Существует вероятность, что это был последний аукцион, когда гелий продавался частным компаниям.

Несмотря на то, что шарики с гелием до сих пор были и остаются в США главным товаром с использованием гелия, этот инертный газ широко востребован в аэрокосмической отрасли, при производстве полупроводников, в научных исследованиях, в медицине (для охлаждения сканеров МРТ) и в других областях. Как компонент смеси для дыхания, гелий используется аквалангистами при работе на глубине, так как он не растворяется в крови человека.

Сегодня гелий чаще всего используется именно как охладитель. У него самая низкая температура кипения среди всех известных веществ - минус 269 градусов Цельсия, поэтому в жидком состоянии гелий - идеальный хладагент. Кипящая жидкость сохраняет температуру, при которой кипит до тех пор, пока остается жидкостью, - она не становится горячее. Вода не может быть горячее ста градусов, и жидкий гелий не может быть горячее -269. Ресурс начали использовать для изоляции сварочных дуг, а позже - в сверхпроводниках, ядерных реакторах и криогенике. Со времен "Манхэттенского проекта" гелий используется для поиска утечек: это инертный газ, который не реагирует с другими веществами и проникает в отверстия очень быстро.

Первыми наступающий дефицит ощущают на себе основные потребители гелия - фирмы, специализирующиеся на товарах для вечеринок. К примеру, акции Party City Holdco Inc - розничного продавца товаров для вечеринок в Северной Америке, рухнули на 30 процентов за последние три года.

Другие интересные новости:

▪ Экран с надувными зонами

▪ Умные бытовые приборы с доступом к сети Интернет

▪ С интернетом мы чувствуем себя умнее

▪ Игровая консоль Anbernic RG Cube

▪ Шаг к биоэлектронике

Лента новостей науки и техники, новинок электроники

 

Интересные материалы Бесплатной технической библиотеки:

▪ раздел сайта Заземление и зануление. Подборка статей

▪ статья Дать добро. Крылатое выражение

▪ статья После показа какого мультфильма в больницы попало около 700 детей? Подробный ответ

▪ статья Силковый узел. Советы туристу

▪ статья Сварочный аппарат с вольтодобавкой и плавной регулировкой тока. Энциклопедия радиоэлектроники и электротехники

▪ статья Радиомикрофон на трех транзисторах. Энциклопедия радиоэлектроники и электротехники

Оставьте свой комментарий к этой статье:

Имя:


E-mail (не обязательно):


Комментарий:





Главная страница | Библиотека | Статьи | Карта сайта | Отзывы о сайте

www.diagram.com.ua

www.diagram.com.ua
2000-2026