Студопедия

КАТЕГОРИИ:


Архитектура-(3434)Астрономия-(809)Биология-(7483)Биотехнологии-(1457)Военное дело-(14632)Высокие технологии-(1363)География-(913)Геология-(1438)Государство-(451)Демография-(1065)Дом-(47672)Журналистика и СМИ-(912)Изобретательство-(14524)Иностранные языки-(4268)Информатика-(17799)Искусство-(1338)История-(13644)Компьютеры-(11121)Косметика-(55)Кулинария-(373)Культура-(8427)Лингвистика-(374)Литература-(1642)Маркетинг-(23702)Математика-(16968)Машиностроение-(1700)Медицина-(12668)Менеджмент-(24684)Механика-(15423)Науковедение-(506)Образование-(11852)Охрана труда-(3308)Педагогика-(5571)Полиграфия-(1312)Политика-(7869)Право-(5454)Приборостроение-(1369)Программирование-(2801)Производство-(97182)Промышленность-(8706)Психология-(18388)Религия-(3217)Связь-(10668)Сельское хозяйство-(299)Социология-(6455)Спорт-(42831)Строительство-(4793)Торговля-(5050)Транспорт-(2929)Туризм-(1568)Физика-(3942)Философия-(17015)Финансы-(26596)Химия-(22929)Экология-(12095)Экономика-(9961)Электроника-(8441)Электротехника-(4623)Энергетика-(12629)Юриспруденция-(1492)Ядерная техника-(1748)

Модуль C R T

Type

Begin

Begin

Begin

Begin

Type

PStroka = ^TStroka;

TStroka = object (TImage)

Str: string; {обрабатываемая строка}

procedure Init(A,B: integer; St: string);

procedure On;

procedure Off;

procedure PrintImage;

end;

procedure TStroka.Init(A,B: integer; St: string);

TImage.Init(A,B);

Str:= St;

end;

procedure TStroka.On;

V:= TRUE;

GotoXY (X,Y);

write (Str);

end;

procedure TStroka.Off;

var

Str1: string;

V:= FALSE;

GotoXY (X,Y);

FillChar(Str1,Length(Str)+1,' ');

{процедура заполняет побайтно переменную символом пробела, начиная с нулевого байта}

Str1[0]:= Chr (Length (Str)); {занесение длины строки в нулевой байт}

write (Str1);

end;

procedure TStroka.PrintImage;

writeln ('Строка: ',Str);

end;

Методы GetX, GetY, Move являются общими для обоих потомков (символа и строки) и не требуют переопределения. Методы Init, On, Off, PrintImage для каждого вида изображений являются индивидуальными и должны быть переопределены заново для каждого объекта. Поскольку объект TImage является абстракцией, тела этих методов в его определении являются пустыми. Теперь нам необходимо обеспечить настройку метода Move на тип объекта: символ или строку. Самое простое решение - традиционное: перед каждым вызовом Move производить анализ экземпляра объекта и в зависимости от результата подключать нужную процедуру On и Off. Мало того, что эта операция достаточно трудоемка, она абсолютно не соответствует концепциям ООП.

Рассмотрим более изящное решение, поддерживаемое объектно-ориентированными средствами. При обращении к методу Move экземпляр потомка вызывает унаследованный от родителя метод Move, который жестко связан с методами TImage.On, TImage.Off, т.к. они были вместе откомпилированы. Связь этих методов - статическая, поскольку она была установлена при компиляции. Чтобы разорвать статическую связь метода Move c методами TImage.On, TImage.Off, которые переопределяются для каждого объекта, объявим эти методы виртуальными. Таким образом существует возможность изменять тот или иной метод объекта в процессе выполнения программы, устанавливая так называемую динамическую связь методов.
Для того, чтобы определить виртуальный метод, необходимо указать после его заголовка в родительском типе служебное слово Virtual. Переопределенные одноименные методы всех потомков должны быть также отмечены как виртуальные. Кроме того, все виртуальные методы должны иметь одинаковый набор формальных параметров. В процессе выполнения программы обеспечивается вызов виртуального метода, соответствующего вызываемому объекту, и один и тот же метод будет работать по-разному, например, метод TImage.PrintImage выводит либо символ, либо строку в зависимости от типа объекта, для которого он вызывается. В этом заключается смысл полиморфизма, когда при вызове одного и того же метода каждый объект может "заказывать" особенности реализации этого метода. Благодаря полиморфизму, удается существенно повысить эффективность разработки больших программных систем. Естественно ожидать, что выполнение программы с виртуальными методами будет происходит несколько медленнее, кроме того требуется дополнительный расход оперативной памяти.

Использование виртуальных методов накладывает дополнительное требование на объектный тип. В этом случае объект должен содержать хотя бы один метод-конструктор, определяющий процедуру создания данного объекта. Синтаксически конструктор объявляется как обычная процедура с заменой ключевого слова Procedure на зарезервированное слово Constructor. Смысл введения конструктора заключается в том, что он дополнительно формирует в экземпляре объекта необходимую информацию для последующих вызовов виртуальных методов. Конструктор должен быть применен к экземпляру объекта до первого вызова виртуального метода. Обычно в качестве конструктора выбирают метод, инициализирующий значения полей экземпляра объекта. Сам конструктор не может быть виртуальным. В нашем примере в качестве конструктора выбрана процедура Init. Теперь объектные типы должны определяться следующим образом:

PImage=^TImage;

TImage= object

...

constructor Init(A,B: integer);

procedure On; virtual;

procedure Off; virtual;

procedure Move(Dx,Dy: integer);

procedure PrintImage; virtual;

...

end;

PSymbol=^TSymbol;

TSymbol= object (TImage)

...

constructor Init(A,B: integer; C: char);

procedure On; virtual;

procedure Off; virtual;

procedure PrintImage; virtual;

end;

Мы уже отмечали, что экземпляры объектов так же, как и переменные любых других типов, можно размещать в динамической памяти с помощью процедуры New. Именно для такого размещения были определены указатели в определении объектных типов PImage, PSymbol и PStroka, например:

var

PS:PSymbol;

...

New (PS); {выделение памяти для экземпляра объекта}

PS^.Init(1,1,Ch);

Dispose (PS); {освобождение памяти}

В последних версиях Турбо-Паскаля допускается расширенный синтаксис процедур New и Dispose:

New (PS, Init(1,1,Ch));

Процедура New не только размещает новый экземпляр объекта в динамической памяти, но и одновременно вызывает конструктор, не используя его составного имени. В этом случае первый параметр PS однозначно определяет, из какого объектного типа берется конструктор.

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

Destructor TImage.Done;

begin end;

Теперь можно использовать расширенный вызов процедуры Dispose с деструктором:

Dispose (PS, Done);

В результате выполнятся действия, описанные в деструкторе Done (если они есть), а затем процедура Dispose освободит количество байтов памяти, соответствующее типу экземпляра объекта PS. Вызов деструктора вне процедуры Dispose естественно не приведет к освобождению памяти, занимаемой экземпляром объекта

 

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

 

Процедуры


ClrScr Очищает экран или окно и помещает курсор в верхний левый угол.
Delay(D: Word) Приостанавливает работу программы на указанное число D миллисекунд. Практически время задержки зависит от тактовой частоты процессора.
GotoXY(X, Y: Byte) Перемещает курсор в позицию X строки Y экрана.
NoSound Выключает источник звука.
Sound(F: Word) Запускает источник звука с частотой F (Гц).
TextBackGround(Color:Byte) Устанавливает цвет фона.
TextColor(Color: Byte) Устанавливает цвет символов.
Window(X1, Y1, X2, Y2: Byte) Определяет текстовое окно на экране. X1, Y1 — координаты левого верхнего угла окна, X2, Y2 — правого нижнего угла окна.

 

Функции


KeyPressed: Boolean Анализирует нажатие клавиши. Результат TRUE, если на клавиатуре нажата клавиша (кроме Alt, Ctrl и т.п.), и FALSE в противном случае. Не задерживает исполнение программы.
ReadKey: Char Читает символ с клавиатуры без эхоповтора на экране. Приостанавливает исполнение программы до нажатия на любую клавишу, кроме Alt, Ctrl и т.п.

<== предыдущая лекция | следующая лекция ==>
Виртуальные методы | Модуль G R A P H
Поделиться с друзьями:


Дата добавления: 2014-01-06; Просмотров: 272; Нарушение авторских прав?; Мы поможем в написании вашей работы!


Нам важно ваше мнение! Был ли полезен опубликованный материал? Да | Нет



studopedia.su - Студопедия (2013 - 2024) год. Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав! Последнее добавление




Генерация страницы за: 0.018 сек.