
- •Объектно-ориентированное программирование
- •Оглавление
- •Введение
- •1. Краткие теоретические сведения
- •1.1. Технология разработки больших программных комплексов
- •1.2. Основные принципы модульного программирования
- •1.3. Объектно-ориентированная методология разработки программ
- •2. Пример объектно-ориентированного программирования
- •2.1. Формулировка задачи
- •2.2. Проектирование структуры объектов
- •2.3. Проектирование методов объектов
- •2.4. Реализация программы
- •2.5. Модификация программы
- •3. Программирование в визуальной среде delphi
- •4. Курсовая работа «объектно-ориентированное программирование»
- •4.1. Основные этапы выполнения курсовой работы.
- •4.2 Варианты курсовой работы
- •5. Литература
- •Объектно-ориентированное программирование
2.3. Проектирование методов объектов
Методы TPoint достаточно простые: Constructor Init заполняет О-поля объекта; процедура Rotate вычисляет новые координаты точки по формулам геометрического поворота вокруг заданной оси на угол step, величина которого зависит от требуемой скорости вращения объекта и процедура Show скорее служит прототипом для дальнейшего наследования, чем для самостоятельного использования. Роль Destructor’a обсуждалась ранее.
В Constructor’e TLine обратите внимание, что объекты pn и pk инициализируются отдельно, поскольку каждый из них должен быть связан с таблицей VMT типа TPoint, а в методе Show значение входного параметра col определяет рисование или стирание линии.
Аналогично осуществляется инициализация сторон квадрата в TSquare и перекрытие виртуальных методов Show и Rotate собственными. После инициализации положение квадрата соответствует верхнему левому углу экрана.
(******** Методы TPoint ********************)
Constructor TPoint .Init ( xx, yy :Real; col :Byte );
Begin x:=xx; y:=yy; Pcolor := col; End;
Procedure TPoint .Rotate ( xOs,yOs :Integer );
Var xx, yy :Real;
Begin xx := (x - xOs)*Cos(step) - (y - yOs)*Sin(step) + xOs;
yy := (x - xOs)*Sin (step) + (y - yOs)*Cos(step) + yOs;
x :=xx; y:=yy;
End;
Procedure TPoint .Show ( col :Byte );
Begin PutPixel ( Round(x), Round(y), Pcolor ); End;
Destructor TPoint .Done;
Begin End;
(******** Методы TLine ********************)
Constructor TLine .Init ( x1,y1,x2,y2 :Real; col :Byte );
Begin pn.Init(x1,y1,col); pk.Init(x2,y2,col); Lcolor:=col; End;
Procedure TLine .Rotate ( xOs,yOs :Integer );
Begin pn.Rotate( xOs,yOs ); pk.Rotate( xOs,yOs ); End;
Procedure TLine .Show ( col :Byte );
Begin
If col=0 Then SetColor ( col ) Else SetColor ( Lcolor ) ;
Line(Round(pn.x),Round(pn.y),Round(pk.x),Round(pk.y));
End;
Destructor TLine .Done;
Begin End;
(***************** Методы TSquare ****************************)
Constructor TSquare .Init ( aa, colK :Byte );
Begin
as := aa; { установка размера стороны квадрата}
Sides[0]. Init ( as, as, 0, as, colK ); { инициализация сторон квадрата }
Sides[1]. Init ( 0, as, 0, 0, colK );
Sides[2]. Init ( 0, 0, as, 0, colK );
Sides[3]. Init ( as, 0, as, as, colK );
Scolor := colK;
End;
Procedure TSquare .Rotate ( xOs, yOs :Integer );
{ реализует вращение квадрата }
Var i :Byte;
Begin
For i:=0 To kv-1 Do Sides[i] .Rotate ( xOs,yOs );
End;
Procedure TSquare .Show( col :Byte );
{ рисует (стирает) изображение квадрата }
Var i :Byte;
Begin
For i := 0 To kv-1 Do Sides[i].Show ( col );
End;
Destructor TSquare .Done;
Begin End;
(***************** Методы TScreen ******************************)
Constructor TScreen .Init ( aa, colK, colG :Byte; dG :Integer );
Var i :Byte;
Begin
GraphInit; { инициализация графического режима VGAHi }
Inherited Init ( aa, colK ); { инициализация родителя }
Gdisp := dG; { задание Y-смещения поверхности качения }
For i := 0 To kv-1 Do With Sides[i] Do Begin
{перенос квадрата на поверхность}
pn.y := pn.y + Gdisp - as;
pk.y := pk.y + Gdisp - as;
End;
Gcolor := colG; { задание цвета поверхности качения }
OsX := as; OsY := Gdisp; { задание начальных координат оси вращения }
angle := 0; { задание начального значения угла поворота }
DrawGround; { рисование поверхности качения }
End;
Procedure TScreen .GraphInit; { инициализация графического режима VGAHi }
Var gd, gm, ErrorCode :Integer;
Begin
gd := Detect;
InitGraph ( gd, gm, ' ');
ErrorCode := GraphResult;
If ErrorCode <> grOk Then Begin
Writeln('Ошибка графики:', GraphErrorMsg ( ErrorCode ) );
Halt(1);
End;
End;
Procedure TScreen .DrawGround; { рисование поверхности качения }
Begin
SetColor ( Gcolor );
Line ( 0, Round( Gdisp + 1 ), GetMaxX, Round( Gdisp + 1 ) );
End;
Function TScreen .ShiftOsXY :Boolean;
{ реализует смещение оси вращения квадрата по оси X}
Begin
If angle > pi/2
Then Begin { если наступил момент переноса оси поворота, }
OsX := OsX + as; { то сместить ось по X на as}
ShiftOsXY := True;
End
Else ShiftOsXY := False;
End;
Procedure TScreen .Go;
{реализует движение квадрата и анимацию его изображения}
Begin
Repeat { цикл возобновления сцены }
Repeat { цикл качения по поверхности и анимации }
angle := angle + step; { накопление угла поворота}
If ShiftOsXY { если была смена оси вращения, }
Then Begin
angle:=0;
Continue; { то пропустить вращение и анимацию }
End;
Rotate ( OsX, OsY ); { вращение квадрата вокруг текущей оси }
Show(Scolor); { рисует изображение квадрата }
Delay( ms ); { задержка }
Show(0); { стирает изображение квадрата }
If KeyPressed Then Exit; { если клавиша нажата, то выход из процедуры}
Until OsX > GetMaxX; { если квадрат достиг правого края экрана, то }
Init ( as, Scolor, Gcolor, Gdisp ); { возобновление сцены }
DrawGround; { рисование поверхности качения }
Until False; { повторение работы до нажатия любой клавиши }
End;
Destructor TScreen .Done;
Begin CloseGraph; End; {закрытие графического режима }
Более сложные действия выполняются в Constructor’e TScreen. После перехода в графический режим осуществляется инициализация квадрата оператором Inherited Init (aa, colK); где ключевое слово Inherited означает – унаследованный, то есть происходит вызов Constructor’a типа TSquare. Отметим, что вызов унаследованного Constructor’a при проектировании Constructor’ов дочерних типов считается хорошим стилем в ООП-программировании. Далее квадрат «устанавливается» на поверхность качения путем коррекции координат Y его вершин на величину смещения этой поверхности на экране. Обратите внимание на оператор With, который, как и при обработке записей, позволяет вынести имя объекта в заголовок и избавляет от необходимости писать длинные составные имена. После этого назначаются координаты оси вращения OsX, OsY, совпадающие с координатами вершины 1 квадрата (см. рис. 2.1). Поскольку рисунок рельефа является статической частью сцены и, при движении квадрата остается неизменной, в конце процедуры следует прорисовка поверхности виртуальным методом DrawGround. Виртуальность метода обусловлена возможностью изменения формы (а значит и метода прорисовки) поверхности качения у потомков. По этой же причине виртуальны метод ShifOsXY ( контролирующий положение оси вращения по мере движения квадрата по поверхности) и метод Go. В последнем реализуются основные действия, происходящие на экране. Метод состоит из двух вложенных циклов: во внутреннем моделируется качение квадрата начиная с левого края до правого края экрана и анимация его изображения, во внешнем – обновление всей сцены и повторение указанных действий. Остальные подробности алгоритмов описанных методов даны в приведенных их текстах.