КАТЕГОРИИ: Архитектура-(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) |
Виртуальные функции
В программе концепция полиморфизма реализуется при помощи виртуальных методов. Виртуальный метод объявляется в базовом объектном типе и в порожденных от базового типах. После его объявления должно быть помещено зарезервированное слово virtual. Виртуальный метод (виртуальная функция) — это метод (или функция) объекта, который может быть переопределён в объектах-наследниках так, что конкретная реализация метода для вызова будет определяться только во время исполнения. Таким образом, программисту необязательно знать точный тип объекта для работы с ним через виртуальные методы: достаточно лишь знать, что объект принадлежит родителю или наследнику, в котором метод объявлен. Виртуальные методы — один из важнейших приёмов реализации полиморфизма. Они позволяют создавать общий код, который может работать как с объектами базового класса, так и с объектами любого его класса-наследника. При этом базовый класс определяет способ работы с объектами и любые его наследники могут предоставлять конкретную реализацию этого способа. Рассмотрим пример 5, указанный ниже. Объектовые типы Tp и Tc содержат поля и методы для рисования, стирания и передвижения точек и окружностей на экране дисплея. Эти два объектовых типа связаны отношениями наследования и содержат одноимённые методы Show (нарисовать), Hide (удалить с экрана) и Moveto (передвинуть). Для различных геометрических фигур алгоритмы методов Show и Hide существенно отличаются. Алгоритм метода Moveto для обеих фигур одинаков (удалить фигуру со старого места, изменить координаты размещения фигуры и нарисовать ту же фигуру на новом месте).Естественным является желание определить метод Moveto для объектового типа Tp и наследовать этот метод без переопределения во всех типах объектов-потомков. Поясним невозможность такого подхода в данной проблеме без дополнительных затрат.Допустим, что метод Moveto определён только в объектовом типе Tp. Если имеются экземпляры двух объектов: var P: Tp; C: Tc;, то вызов метода P.Moveto начнёт своё выполнение с метода Tp.Hide. Последующие действия метода Moveto приведут к ожидаемому результату. Теперь рассмотрим вызов C.Moveto. Экземпляр типа-потомка вызывает унаследованный метод Moveto, который жёстко связан с методами Tp.Show и Tp.Hide. Методы Show, Hide, Moveto были откомпилированы в одном контексте – в одном объектовом типе Tp. Поэтому метод Moveto всегда будет вызывать методы Tp.Show и Tp.Hide. Связь этих методов является статической, так как она была определена при компиляции. Методы С.Show и С.Hide вызваны не будут. Вызов С.Moveto приведёт к перемещению точки.Если мы хотим иметь один метод Moveto для различных объектов, необходимо разорвать статическую связь этого метода с методами Show иHide и обеспечить возможность для метода Moveto вызывать либо методы Tp.Show и Tp.Hide, либо Tс. Show и Tс. Hide в зависимости от того, какой объект вызывает метод Moveto. Такой механизм называют динамическим или поздним связыванием в отличие от статического или раннего связывания. Он достигается введением виртуальных методов.Для определения метода как виртуального после заголовка метода в объектовом типе указывается служебное слово VIRTUAL. При виртуализации методов должны выполняться следующие условия:1) если прародительский объектовый тип описывает метод как виртуальный, производные типы метод с тем же именем также должны описывать как виртуальный;2) заголовок в заново определённом виртуальном методе не может быть изменён;3) если объектовый тип содержит виртуальный метод, он должен содержать хотя бы один метод-конструктор;4) метод-конструктор должен быть применён к экземпляру объекта до первого вызова виртуального метода;5) каждый экземпляр объекта должен быть инициализирован отдельным вызовом конструктора;6) сам конструктор не может быть виртуальным. Пример 5. Текст программы, использующий виртуальные методы, может быть следующим:Uses Crt, Graph;Var gd,gm: integer;Type Tp = Object X,y,c: integer;Constructor Init (ax,ay,ac: integer); Procedure Show; Virtual; Procedure Hide; Virtual; Procedure Moveto (dx,dy: integer); End;Constructor Tp. Init; Begin X:=ax; y:=ay; c:=ac End;Procedure Tp. Show; Begin Putpixel(x,y,c); End;Procedure Tp. Hide; Begin Putpixel(x,y,Getbkcolor) End;Procedure Tp. Moveto; BeginDelay(1000); Hide; X:=x+dx; y:=y+dy; Show End; Type Tc = Object (Tp) R: integer;Constructor Init (ax,ay,ac,ar: integer); Procedure Show; Virtual; Procedure Hide; Virtual; End;Constructor Tc. Init; Begin Inherited(ax,ay,ac); R:=ar End;Procedure Tc. Show; Begin Setcolor(c); Circle(x,y,r) End;Procedure Tc. Hide; Begin Setcolor(Getbkcolor); Circle(x,y,r) End;Var P: Tp; C: Tc;BeginGd:=Detect;Initgraph(Gd,Dm,’d:\bp\bgi’);P. Init (100,120,yellow); P. Show; P. Moveto (50,50); Readln;C.Init (200,300,Green,150); C. Show; C.Moveto (10,10); Readln;ClosegraphEnd. Пример 6. Пример использования виртуальных методов при работе с вектором и матрицей (предусмотрим ввод значений элементов рассматриваемой структуры данных, нахождение в структуре элемента с минимальным значением и вывод результата).const nmax=10;type tvect = array[1..nmax] of real;tmatr = array[1..nmax,1..nmax] of real; vect = object n:integer;{фактический размер вектора, количество строк матрицы } min: real; a: tvect; constructor init; procedure inpt; virtual; {ввод} procedure obr; virtual; {нахождение минимального элемента} procedure out; {вывод} procedure work;{полная обработка структуры данных} end;constructor vect. init; begin end;procedure vect. inpt;var i: integer;begin writeln('n=?'); readln(n); for i:=1 to n do begin write('a[i]-?'); readln(a[i]) end;end;procedure vect. obr;var i: integer;begin min:=a[1]; for i:=2 to n do if a[i]<min then min:=a[i]end;procedure vect. out;begin writeln('min=',min:7:3) end;procedure vect. work;begin inpt; obr; out end; type matr =object(vect) m: integer; {количество столбцов матрицы} b: tmatr; procedure inpt; virtual;{ввод} procedure obr; virtual;{нахождение мин. элемента} end;procedure matr. inpt;var i,j: integer;begin writeln('n,m=?'); readln(n,m); for i:=1 to n do for j:=1 to m do begin writeln('b[i,j]=?'); readln(b[i,j]) end;end;procedure matr. obr;var i,j: integer;begin min:=b[1,1]; for i:=1 to n do for j:=1 to m do if b[i,j]<min then min:=b[i,j]end; var ObjVect: vect; ObjMatr: matr;begin ObjVect. init; ObjVect. work; ObjMatr. init; ObjMatr. work;readln end.Контрольные вопросы 1. Дайте определение понятию «виртуальная функция».
Дата добавления: 2014-01-04; Просмотров: 281; Нарушение авторских прав?; Мы поможем в написании вашей работы! Нам важно ваше мнение! Был ли полезен опубликованный материал? Да | Нет |