Навигация
Главная
Поиск
Форум
FAQ's
Ссылки
Карта сайта
Чат программистов

Статьи
-Delphi
-C/C++
-Turbo Pascal
-Assembler
-Java/JS
-PHP
-Perl
-DHTML
-Prolog
-GPSS
-Сайтостроительство
-CMS: PHP Fusion
-Инвестирование

Файлы
-Для программистов
-Компонеты для Delphi
-Исходники на Delphi
-Исходники на C/C++
-Книги по Delphi
-Книги по С/С++
-Книги по JAVA/JS
-Книги по Basic/VB/.NET
-Книги по PHP/MySQL
-Книги по Assembler
-PHP Fusion MOD'ы
-by Kest
Professional Download System
Реклама
Услуги

Автоматическое добавление статей на сайты на Wordpress, Joomla, DLE
Заказать продвижение сайта
Программа для рисования блок-схем
Инженерный калькулятор онлайн
Таблица сложения онлайн
Популярные статьи
OpenGL и Delphi... 65535
Форум на вашем ... 65535
21 ошибка прогр... 65535
HACK F.A.Q 65535
Бип из системно... 65535
Гостевая книга ... 65535
Invision Power ... 65535
Пример работы с... 65535
Содержание сайт... 65535
ТЕХНОЛОГИИ ДОСТ... 65535
Организация зап... 65535
Вызов хранимых ... 65535
Создание отчето... 65535
Имитационное мо... 65535
Программируемая... 65535
Эмулятор микроп... 65535
Подключение Mic... 65535
Создание потоко... 65535
Приложение «Про... 65535
Оператор выбора... 65535
Реклама
Сейчас на сайте
Гостей: 22
На сайте нет зарегистрированных пользователей

Пользователей: 13,372
новичок: vausoz
Новости
Реклама
Выполняем курсовые и лабораторные по разным языкам программирования
Подробнее - курсовые и лабораторные на заказ
Delphi, Turbo Pascal, Assembler, C, C++, C#, Visual Basic, Java, GPSS, Prolog, 3D MAX, Компас 3D
Заказать программу для Windows Mobile, Symbian

Диплом RSA, ЭЦП, сертификаты, шифрование на C#
Компьютерный магазин на Turbo Pascal (База данных) + Пояснительная записка
Моделирование интернет кафе на GPSS + Отчет

Объектно-ориентированное программирование. Виртуальные методы и полиморфизм


Из описания видно, что метод move обращается к методам, для того, чтобы сначала сделать объект невидимым (вызов метода hide), затем изменить его координаты, а затем вновь отобразить объект на экране (вызов метода show). В случае, когда данный метод используется в отношении объекта dot, то все работает нормально (точка при нажатии соответствующих кла-виш гаснет, и затем зажигается в новом месте), т.к. методы hide и show являются для данного объекта «родными». Если же попытаться вызвать метод move для объекта-окружности (circl.move), то система попытается найти метод с таким именем в описании объектного типа circl, и не найдя его, продолжит поиск в описании типа-предка. В результате произойдет обращение к методу dot.move. После этого из метода circl.move должны быть вызваны переопределенные методы circl.hide и circl.show. Однако этого не происходит: из унаследованного метода do.move экземпляр объекта obj2 вызывает методы объекта-предка dot.hide и dot.show. Это объясняется тем, что методы dot.hide, dot.move и dot.show жестко связаны, т.к. были откомпилированы в едином контексте – объектном типе dot, и связь между этими методами, установленная во время компиляции носит статический характер. В этом случае будет перемещена точка, а не окружность.
Избежать подобных ситуаций позволяет механизм, известный как динамическое (или позднее) связывание – в отличие от статического (или раннего) связывания. Указанный механизм реализуется через использование так называемых виртуальных методов. Описание объектов, содержащих виртуальные методы, имеет некоторые особенности. Заголовок виртуального метода в описании объектного типа дополняется зарезервированным словом VIRTUAL. Если в потомках этого объектного типа имеются переопределенные методы (т.е. методы с тем же именем), они также должны быть объявлены как виртуальные и при этом иметь тот же набор формальных параметров, что и метод объекта-предка. Кроме того, в объектном типе, имею-щем хотя бы один виртуальный метод, должен быть и специальный метод – конструктор, который обязательно должен быть применен к экземпляру объекта до первого обращения к виртуальному методу. Конструктор обычно представляет собой метод, задающий для объекта некоторые начальные значения (т.е. выполняет его инициализацию). Конструктор может быть либо определен в данном объекте, либо унаследован от объекта-предка. При этом сам конструктор виртльным быть не может.
Вот как будет выглядеть описание объектных типов dot и circl с виртуальными методами.
type dot = object
x,y: integer;
constructor Init(a,b: integer);
procedure show; virtual;
procedure hide; virtual;
procedure move(Dx,Dy:integer);
end;
circl= object (dot)
r:integer;
constructor Init(a,b,rad: integer);
procedure show; virtual;
procedure hide; virtual;
end;
constructor dot.Init;
begin
x:=a;
y:=b;
end;

constructor circl.Init;
begin
x:=a;
y:=b;
r:=rad;
end;

procedure dot.show;
begin
PutPixel(x,y,white);
end;

procedure circl.show;
begin
setcolor(yellow);
circle(x,y,r);
end;

procedure dot.Hide;
begin
PutPixel(x,y,black);
end;

procedure circl.hide;
begin

setcolor(black);
circle(x,y,r);
end;

procedure Dot.move;
begin
hide;
x:=x+Dx; y:=y+Dy;
show;
end;



Теперь при вызове метода move экземпляром obj2 система обращается к методу dot.move, унаследованному от предка. В этом методе сначала происходит обращение к методу hide (делает объект невидимым), затем - изменение координат центра окружности, и, наконец, - к методу show. А поскольку методы hide и show объявлены как виртуальные, то Turbo Pascal обеспечива-ет обращение именно к тому виртуальному методу, который определен для вызывающего объекта, т.е. будут вызваны методы circl.hide и circl.show.
Ниже представлен полный текст программы, которая рисует и перемещает точку или окружность (в зависимости от выбора пользователя). В этой программе следует обратить внимание на вызовы метода move в теле программы. Этот метод вызывается как для объекта-точки (dot.move), так и для объекта-окружности (circl.move). Однако метод move – единственный. Он объявлен в объекте dot и унаследован объектом circl. Другими словами, один и тот же метод move работает по-разному (перемещает точку или окружность) – в зависимости от того, какой объект его вызывает. Такое свойство называется полиморфизм.

program ex_obj3;
uses crt,graph;
type dot = object
x,y: integer;
constructor Init(a,b: integer);
procedure show; virtual;
procedure hide; virtual;
procedure move(Dx,Dy:integer);
end;
circl= object (dot)
r:integer;
constructor Init(a,b,rad: integer);
procedure show; virtual;
procedure hide; virtual;
end;

constructor dot.Init;
begin
x:=a;
y:=b;
end;

constructor circl.Init;
begin
x:=a;
y:=b;
r:=rad;
end;

procedure dot.show;
begin
PutPixel(x,y,white);
end;

procedure circl.show;
begin
setcolor(yellow);
circle(x,y,r);
end;

procedure dot.Hide;
begin
PutPixel(x,y,black);
end;

procedure circl.hide;
begin

setcolor(black);
circle(x,y,r);
end;

procedure Dot.move;
begin
hide;
x:=x+Dx; y:=y+Dy;
show;
end;

Var i,j,err:integer;
c:char;
dot1:dot;
obj2:circl;
begin
i:=detect;
InitGraph(i,j,'');
err:=GraphResult;
if err<>0 then
writeln(graphErrorMsg(err))
else
begin
repeat
setcolor(yellow);
OutTextXY(getMaxX div 4,GetMaxY-30,'press 1 for draw pixel, 2 for draw cirlce, ESC- exit');
c:=readkey;
case c of {выбор типа графического объекта}
{1} #49: {точка}
with dot1 do
begin
init(100,100);
show;
repeat
c:=readkey;
case c of
#0:
begin
c:=readkey;
case c of
#72: move(0,-5);
#80: move(0,5);
#77: move(5,0);
#75: move(-5,0);
end;
end;
#27: hide;
end; {case}
until (c=#27) or (c=#13);

end;
{2} #50: {окружность}
begin
obj2.init(100,100,30);
obj2.show;
repeat
c:=readkey;
case c of
#0:
begin
c:=readkey;
case c of
#72: obj2.move(0,-5);
#80: obj2.move(0,5);
#77: obj2.move(5,0);
#75: obj2.move(-5,0);
end;
end;
#27: obj2.hide;
end;
until (c=#27) or (c=#13);
end;
{ESC}#27: halt;
end;
until false;
end;
end.


Опубликовал Kest June 03 2010 15:18:43 · 0 Комментариев · 10231 Прочтений · Для печати

• Не нашли ответ на свой вопрос? Тогда задайте вопрос в комментариях или на форуме! •


Комментарии
Нет комментариев.
Добавить комментарий
Имя:



smiley smiley smiley smiley smiley smiley smiley smiley smiley
Запретить смайлики в комментариях

Введите проверочный код:* =
Рейтинги
Рейтинг доступен только для пользователей.

Пожалуйста, залогиньтесь или зарегистрируйтесь для голосования.

Нет данных для оценки.
Гость
Имя

Пароль



Вы не зарегистрированны?
Нажмите здесь для регистрации.

Забыли пароль?
Запросите новый здесь.
Поделиться ссылкой
Фолловь меня в Твиттере! • Смотрите канал о путешествияхКак приготовить мидии в тайланде?
Загрузки
Новые загрузки
iChat v.7.0 Final...
iComm v.6.1 - выв...
Visual Studio 200...
CodeGear RAD Stud...
Шаблон для новост...

Случайные загрузки
Основы Delphi
MiniTetris [Исход...
Turbo Pascal for ...
Мониторинг сервер...
Converter AMR<->W...
Программа для рис...
Расширенный загру...
Srinilist
Простой пример ка...
Распознавание тек...
Фундаментальные а...
Прграммирование в...
Таймер и секундомер
PHP: Полезные приемы
Защита от спама ...
SUIPack
Degisy Data Acces...
100 компонентов о...
Borland Delphi 8 ...
Доступа к БД Fire...

Топ загрузок
Приложение Клие... 100774
Delphi 7 Enterp... 97839
Converter AMR<-... 20268
GPSS World Stud... 17014
Borland C++Buil... 14193
Borland Delphi ... 10293
Turbo Pascal fo... 7374
Калькулятор [Ис... 5984
Visual Studio 2... 5207
Microsoft SQL S... 3661
Случайные статьи
Получая пакеты, бр...
Логическая бомба н...
ПРИЛОЖЕНИЕ 3. Стан...
Gamepark 32 (GP32)
Различные команды ...
Архитектура ОП дол...
Каковы значения ад...
Табл. 3. Анализ те...
Краткие выводы по ...
Перечислимый тип в...
Покупка доменов ru.
Несколько слов о п...
Гриб маслята
Запрос дерева со С...
Про закон Парето в...
Применение техноло...
File not found
Установка IBM WebS...
Квартира в Новой У...
Найдите печатный т...
Задача о коммивояж...
Разреженные массивы
Группа блоков созд...
Усовершенствование...
Решения к главе 4
Статистика



Друзья сайта
Программы, игры


Полезно
В какую объединенную сеть входит классовая сеть? Суммирование маршрутов Занимают ли таблицы память маршрутизатора?