В зависимости от того, какие действия происходят при вызове, методы делятся на следующие группы:
По умолчанию все методы статические. Эти методы полностью перекрываются в классах-потомках при их переопределении. При этом можно полностью изменять объявление метода (например, тип и количество параметров).
Виртуальные и динамические методы имеют в базовом и производном классе те же имена и типы. В классах наследниках эти методы перегружены.
Разница между виртуальными и динамическими - способ их вызова... Использование виртуальных методов требует больший расход памяти..., зато они вызываются быстрее.
Пример был взят из учебника Free Pascal и Lazarus (Е.Р. Алексеев, О.В. Чеснокова, Т.В. Кучер), где он описан для среды Lazarus и с графическим интерфейсом.
Здесь приводится для IDE Free Pascal.
program project1; {$mode objfpc}{$H+} uses {$IFDEF UNIX}{$IFDEF UseCThreads} cthreads, {$ENDIF}{$ENDIF} Classes { you can add units after this }; type TTriangle = class Private x,y: array[0..2] of real; Public constructor Create; procedure Set_Tr(a,b: array of real); function a():real; function b():real; function c():real; function Proverka():boolean; virtual; function Perimetr():real; function Square():real; procedure Show(); virtual; end; type R_TTriangle = class(TTriangle) Public function Proverka():boolean; override; procedure Show(); override; end; constructor TTriangle.Create; var i: integer; begin for i:=0 to 2 do begin x[i]:=0; y[i]:=0; end; end; procedure TTriangle.Set_Tr(a,b: array of real); var i: integer; begin for i:=0 to 2 do begin x[i]:=a[i]; y[i]:=b[i]; end; end; function TTriangle.a():real; begin a := sqrt(sqr(x[1]-x[0]) + sqr(y[1]-y[0])); end; function TTriangle.b():real; begin b := sqrt(sqr(x[2]-x[1]) + sqr(y[2]-y[1])); end; function TTriangle.c():real; begin c := sqrt(sqr(x[0]-x[2]) + sqr(y[0]-y[2])); end; function TTriangle.Perimetr():real; begin Perimetr := a() + b() + c(); end; function TTriangle.Square():real; var p: real; begin p := Perimetr()/2; Square := sqrt((p-a()) * (p-b()) * (p-c())); end; function TTriangle.Proverka():boolean; begin if (x[0]-x[1])/(x[0]-x[2])= (y[0]-y[1])/(y[0]-y[2]) then Proverka := false else Proverka := true; end; procedure TTriangle.Show(); begin if Proverka() then begin writeln('a=',a(),', b=',b(),', c=',c()); writeln('P=',Perimetr(),', S=',Square()); end; end; function R_TTriangle.Proverka():boolean; begin if (a()=b()) and (c()=b()) then Proverka := false else Proverka := true; end; procedure R_TTriangle.Show(); begin if Proverka() then begin writeln('a=',a()); writeln('P=',Perimetr(),', S=',Square()); end; end; var figura1: TTriangle; figura2: R_TTriangle; var x1,y1,x2,y2: array[1..3] of real; begin write('1 coords: '); readln(x1[1],y1[1]); write('2 coords: '); readln(x1[2],y1[2]); write('3 coords: '); readln(x1[3],y1[3]); write('1 coords: '); readln(x2[1],y2[1]); write('2 coords: '); readln(x2[2],y2[2]); write('3 coords: '); readln(x2[3],y2[3]); figura1 := TTriangle.Create; figura2 := R_TTriangle.Create; figura1.Set_Tr(x1,y1); figura2.Set_Tr(x2,y2); figura1.Show(); figura2.Show(); figura1.Free; figura2.Free; readln; end.
Вторая программа с демонстрацией наследования:
program project1; {$mode objfpc}{$H+} uses {$IFDEF UNIX}{$IFDEF UseCThreads} cthreads, {$ENDIF}{$ENDIF} Classes { you can add units after this }; type TFigure = class private n: integer; // количество сторон p: array of real; // массив длин сторон public // абстрактные подпрограммы // в каждом производном классе будут перегружаться constructor Create; virtual; abstract; function Perimeter(): real; function Square(): real; virtual; abstract; procedure Show(); virtual; abstract; end; type TCircle = class(TFigure) public constructor Create; override; function Perimeter(): real; function Square(): real; override; procedure Show(); override; end; type TRectangle = class(TFigure) public constructor Create; override; function Square(): real; override; procedure Show(); override; end; function TFigure.Perimeter(): real; var i: integer; s: real; begin s := 0; for i:=0 to n-1 do s := s + p[i] + p[i]; Perimeter := s; end; constructor TCircle.Create; begin n := 1; SetLength(p,n); // выделяем память под 1 элемент массива p[0] := 5; // радиус окружности end; function TCircle.Perimeter(): real; begin Perimeter := 2 * PI * p[0]; // длина окружности end; function TCircle.Square(): real; begin Square := PI * sqr(p[0]); end; procedure TCircle.Show(); begin writeln('r=',p[0]:4:2,' P=',Perimeter():4:2, ' S=', Square():4:2); end; constructor TRectangle.Create; begin n := 2; SetLength(p,n); // выделяем память под 2 элемента p[0] := 4; p[1] := 2; end; function TRectangle.Square(): real; begin Square := p[0] * p[1]; end; procedure TRectangle.Show(); begin writeln('a=',p[0]:4:2,' b=',p[1]:4:2,' P=',Perimeter():4:2, ' S=', Square():4:2); end; var figura1: TCircle; figura2: TRectangle; begin figura1 := TCircle.Create; figura2 := TRectangle.Create; figura1.Show(); figura2.Show(); readln end.
Последние комментарии
1 день 15 часов назад
1 день 23 часа назад
2 дня 5 часов назад
3 дня 12 часов назад
6 дней 7 часов назад
6 дней 8 часов назад
1 неделя 7 часов назад
1 неделя 1 день назад
1 неделя 1 день назад
1 неделя 1 день назад