КАТЕГОРИИ: Архитектура-(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, которые переопределяются для каждого объекта, объявим эти методы виртуальными. Таким образом существует возможность изменять тот или иной метод объекта в процессе выполнения программы, устанавливая так называемую динамическую связь методов. Использование виртуальных методов накладывает дополнительное требование на объектный тип. В этом случае объект должен содержать хотя бы один метод-конструктор, определяющий процедуру создания данного объекта. Синтаксически конструктор объявляется как обычная процедура с заменой ключевого слова 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 естественно не приведет к освобождению памяти, занимаемой экземпляром объекта
Процедуры
Функции
Дата добавления: 2014-01-06; Просмотров: 301; Нарушение авторских прав?; Мы поможем в написании вашей работы! Нам важно ваше мнение! Был ли полезен опубликованный материал? Да | Нет |