2.4 Полиморфизм

 

Объект-потомок может не только дополнять поля и методы родителя, но и заменять методы родителя на новые (заменять поля родителя нельзя!). Например, вместо правила SETLINEVISIBLE мы могли бы в объекте TLINE объявить правило SETVISIBLE, которое в этом случае перекроет (заменит собой) одноименное правило объекта-родителя TPOINT. В результате, к разным родственным объектам TPOINT и TUNE можно было бы применять одноименные правила SETVISIBLE, обеспечивающие сходные в смысловом отношении действия - показать или сделать невидимым графический объект. Свойства, позволяющее называть разные алгоритмические действия одним именем, называется полиморфизмом.

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

Появление директивы VIRTUAL в объявлении метода как бы предупреждает компилятор: «Пока ты не знаешь, что я хочу. Придет время -запроси образец!». Встретившись с таким объявлением, компилятор не будет устанавливать связь объекта с методом. Вместо этого он создаст специальную таблицу, которая называется таблицей виртуальных методов (ТВМ). В этой таблице хранятся адреса точек входа всех виртуальных методов. Для каждого типа объекта создается своя ТВМ и каждый экземпляр объекта пользуется этой единственной для объектов данного типа таблицей. ТВМ обеспечивает работающую программу механизмом связывания объекта с полями. Фактическое связывание осуществляется с помощью обращения к конструктору - специальному методу, который во всем подобен обычной процедуре, но в заголовке вместо PROCEDURE содержит зарезервированное слово CONSTRUCTOR. В момент обращения к конструктору в специальное поле объекта заносится адрес нужной ТВМ, в результате чего все виртуальные методы (в том числе и унаследованные от родителей!) получают доступ к нужным полям.

Конструктор может не обращаться к виртуальному методу и даже вообще быть пустым, т.е. не иметь никаких исполняемых операторов (как в нашем примере), тем не менее, объект будет инициализирован правильно. Дело в том, что заголовок CONSTRUCTOR предписывает компилятору создать специальный набор машинных инструкций, который инициализирует ТВМ и исполняется в момент обращения к конструктору до выполнения его (конструктора) содержательной части. В объекте может быть сколько угодно конструкторов, но ни один из них не может быть виртуальным.

Выбор того, каким именно - статическим или виртуальным - должен быть метод, зависит от специфики задачи и Ваших вкусов. Однако следует помнить, что статический метод никогда не может быть перекрыт виртуальным и наоборот. Список формальных параметров статического метода может отличаться от списка в перекрываемом методе, а для виртуальных методов оба списка должны быть идентичны. И, наконец, виртуальные объекты занимают несколько большую память (за счет ТВМ) и вызов виртуальных методов исполняется чуть медленнее, чем вызов статических. Тем не менее, всегда, когда это возможно, следует отдавать предпочтение виртуальным методам, т.к. они придают программе дополнительную гибкость. Всегда может оказаться, что рано или поздно мы или кто-то из пользователей нашей библиотеки захочет модифицировать ту или иную ее функции. В этом случае перекрытие виртуальных методов позволит предельно упростить задачу. Отметим, что стандартная функция Турбо Паскаля TypeOf(TObj) возвращает ссылку на ТВМ для объекта типа TObj. Эту ссылку можно использовать, например, для проверки того, с каким именно объектом работает в данный момент виртуальный метод:

If TypeOf(Self) - TypeOf(TA) then ...

И еще одно замечание. Между экземплярами родственных объектов возможен обмен информацией с помощью операторов присваивания. Например, если PoinTl и Point2 - экземпляры объекта TPOINT, то допустимо присваивание 
             Point1 := Point2;

или 
             PoinT2 := Point1;

Присваивания разрешены и между экземплярами родственных объектов разных уровней иерархии, однако в этом случае экземпляру объекта-родителя можно присвоить экземпляр потомка, но не наоборот! Например, разрешается присваивание
             Point := Line;

но недопустимо

      Line := Point;

если LINE - потомок POINT. Это происходит по той причине, что потомок содержит все поля родителя, поэтому при присваивании потомка родителю эти поля получат правильные значения. Обратное же присваивание оставит без изменения «лишние» поля потомка, что является недопустимым.
При использовании виртуальных правил следует остерегаться присваивания между экземплярами объектов, во всяком случае, необходимо помнить, что простое присваивание не заменяет собой инициацию виртуального объекта. Если, например, LINE и POINT - виртуальные объекты, то присваивание
                 POINT:= Line;

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


Заключение

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

Турбо Паскаль – достаточно «старый» программный продукт. Следует заметить, однако, что Паскаль – это живой язык. Известны, используются или находятся в стадии разработки компиляторы и среды разработки программ на Паскале для различных операционных систем, в том числе и бурно развивающейся операционной системы Linux. Эти системы иногда частично, а иногда и в значительной мере совместимы с Турбо Паскалем, а следовательно, накопленный опыт может быть использован и для серьезной, профессиональной работы по разработке программ.

Список используемых источников

1.   Абрамов В.Г., Трифонов Н.П., Трифонова Г.Н. Введение в язык Паскаль. - М.: Наука, 1988. - 320 с.

2.   Абрамов С.А., Зима Е.В. Начала программирования на языке Паскаль. - М.: Наука, 1987. - 112 с.

3.   Вирт Н. Алгоритмы и структуры данных./Пер. с англ. М.: Мир, 1989. - 360 с.

4.   Грогоно П. Программирование на языке Паскаль. - М.: Мир, 1982. - 382 с.

5.   Дантеманн Дж., Мишел Дж., Тейлор Д. Программирование в среде Delphi: Пер. с англ. - Киев: НИПФ “ДиаСофтЛтд.”, 1995. - 608 с.

6.   Епанешников А., Епанешников В. Программирование в среде Турбо Паскаль 7.0. - М.: ДИАЛОГ-МИФИ, 1993. - 288 с.

7.   Йенсен К., Вирт Н. Паскаль. Руководство для пользователя и описание языка: Пер. с англ. - М.: Финансы и статистика, 1982. - 151 с.

8.   Матчо Дж., Фолкнер Д.Р. Delphi: Пер.с англ.- М.: БИНОМ, 1995. - 464 с.

9.   Орлик С.В. Секреты Delphi на примерах: - М.: БИНОМ. - 316 с.

10.         Перминов О.Н. Программирование на языке Паскаль. - М.: Радио и связь, 1988. - 224 с.

11.         Пильшиков В.Н. Сборник упражнений по языку Паскаль: Учеб. пособие для вузов. - М.: Наука, 1989. - 160 с.

12.         Прайс Д. Программирование на языке Паскаль: Практ. руководство. - М.: Мир, 1987. - 232 с.

13.         Рубенкинг Н. Турбо Паскаль для Windows: В 2 т.; Пер. с англ. - М.: Мир, 1993. - 536 с.

14.         Фаронов В.В. Турбо Паскаль. В 3-х книгах. Книга 1. Основы Турбо Паскаля. - М.: Учеб.-инж.центр МВТУ-ФЕСТО ДИДАКТИК, 1992. - 304 с.

15.         Фаронов В.В. Паскаль и Windows. - М.: Учеб.-инж.центр МВТУ-ФЕСТО ДИДАКТИК, 1994. - 539 с.

16.         Фаронов В.В. Практика Windows-программирования. М.: Информпечать, 1996. - 247 с.

17.         Федоров А., Рогаткин Д. Borland Pascal в среде Windows. - Киев: Диалектика, 1993. - 656 с.

18.         Форсайт Р. Паскаль для всех: Пер. с англ.- М.: Машиностроение, 1986. - 288 с.

Приложение А

(обязательное)

{$N+}

unit func1;

interface

type

float = Extended;

const

Infinity = 1.0E+4932;

function Tan(x : float) : float;

function ArcSin(x : float) : float;

function ArcCos(x : float) : float;

function Degrees_to_Radians(Degrees : float) : float;

function Radians_to_Degrees(Radians : float) : float;

function Sinh(x : float) : float;

function Cosh(x : float) : float;

function Tanh(x : float) : float;

function Log10(x : float) : float;

function Power(x, Exponent : float) : float;

implementation

const

Radians_Per_Degree = Pi / 180;

Degrees_Per_Radian = 180 / Pi;

Ln10 = 2.3025850930;

MaxValue = 88.029619;

function Tan(x : float) : Float;

var

Consine, Tangent : float;

begin

Consine := Cos(x);

if Cosine := 0.0 then

if Sin(x)>=0 then

Tan := Infinity

else

Tan := -Infinity

else

begin

Tangent := Sin(x) / Cosine;

if Tangent > Infinity then

Tan := Infinity

else

if Tangent < -Infinity then

Tan := -Infinity

else

Tan := Tangent;

end;

end;

function ArcSin(x : float) : float;

begin

if Abs(x) = 1.0 then

ArcSin := Pi / 2.0

else

ArcSin := ArcTan(x / Sqrt(1 – x * x));

end;

function ArcCos(x : float) : float;

var

Result : float;

begin

if x = 0.0 then

ArcCos := Pi / 2.0

else

begin

Result := ArcTan(sqrt(1 – x * x) / x);

if x < 0.0 then

ArcCos := Result + Pi

else

ArcCos := Result;

end;

end;

function Degrees_to_Radians(Degrees : float) : float;

begin

Degrees_to_Radians := Degrees * Radians_Per_Degree;

end;

function Radians_to_Degrees(Radians : float) : float;

begin

Radians_to_Degrees := Radians * Degrees_Per_Radian;

end;

function Sinh(x : float) : float;

var

t : float;

begin

if x > MaxValue then

Sinh := Ifinity

else

if x < -MaxValue then

Sinh := -Infinity

else

begin

t := Exp(x);

Sinh := 0.5 * (t – 1 / t);

end;

end;

function Cosh(x : float) : float;

var

t : float;

begin

if Abs(x) > MaxValue then

Cosh := Infinity

else

begin

t := Exp(x);

Cosh := 0.5 * (t + 1 / t);

end;

end;

function Tanh(x : float) : float;

begin

Tanh := Sinh(x) / Cosh(x);

end;

function Log10(x : float) : float;

begin

Log10 := Ln(x) / Ln10;

end;

function Power(x, Exponent : float) : float;

begin

if x > 0.0 then

Power := Exp(Exponent * Ln(x))

else if x = 0.0 then

Power := 0.0

else

WriteLn ( ‘ Основание степени отрицательно! ’ );

end;

begin

end.


Информация о работе «Модули и объекты в языке Турбо Паскаль 7.0»
Раздел: Информатика, программирование
Количество знаков с пробелами: 47594
Количество таблиц: 1
Количество изображений: 0

Похожие работы

Скачать
100912
12
2

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

Скачать
17572
2
0

... выбрать режим Quit <Alt>-<X>, после чего нажать либо <Enter>, либо комбинацию <Alt>-<X>. ФУНКЦИОНАЛЬНЫЕ КЛАВИШИ Функциональные клавиши используются для управления средой Турбо Паскаля. Они обозначаются F1, F2,..., F12 и располагаются в самом верхнем ряду клавиатуры. С каждой из этих клавиш связывается некоторая команда меню. Действие почти всех функциональных ...

Скачать
12936
3
0

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

Скачать
112819
0
0

... . Объясните, для чего служат разрешения и привилегии в Windows NT. Зав. кафедрой --------------------------------------------------   Экзаменационный билет по предмету СИСТЕМНОЕ ПРОГРАММНОЕ ОБЕСПЕЧЕНИЕ Билет № 22 Перечислите возможности и инструменты системы программирования Microsoft Developer Studio. Укажите для чего предназначается буфер в системах ввода-вывода, ...

0 комментариев


Наверх