Конспект лекций по дисциплине «Высокоуровневые методы информатики и программирования» для студентов специальности 080801 «Прикладная информатика в экономике»
Вид материала | Конспект |
- Темы курсовых работ по дисциплине «Высокоуровневые методы информатики и программирования», 82.9kb.
- Рабочая программа по дисциплине: «высокоуровневые методы информатики и программирования», 127.42kb.
- Курс Методы визуального программирования при разработке системного программного обеспечения., 30.14kb.
- Учебно-методический комплекс «Высокоуровневые методы информатики и программирования», 569.1kb.
- Рабочая программа по дисциплине «Исследование операций в экономике» для специальности, 137.37kb.
- Рабочая программа по дисциплине "Имитационное моделирование экономических процессов", 207.47kb.
- Рабочая программа по дисциплине «Математическая экономика» для специальности 080801, 222.52kb.
- Рабочая программа по дисциплине "Технико-экономический анализ деятельности предприятий", 356.09kb.
- Рабочая программа по дисциплине "Финансы и кредит" Для специальности 080801 Прикладная, 181.17kb.
- Рабочая программа по дисциплине "алгоритмизация и программирование" для специальности, 136.39kb.
2.6.Композиция и наполнение
Для реализации объектов, находящихся между собой в отношении включения (рис. 1.15) могут быть использованы механизмы наследования или композиции.
Композицией называется такое отношение между классами, когда один является частью второго.
Композиция реализуется включением в класс объектных полей и применяется в тех случаях, когда наследование по каким-либо причинам невозможно или не целесообразно.
Borland Pascal 7.0 предоставляет возможность использования в классах объектных полей. Рассмотрим это на примере.
^ Пример 2.27. Использование объектных полей
Ниже приведен текст программы, в которой класс Выводимая строка (OutS) объявлен как часть класса Окно (Win). Это реализовано включением в структуру класса Win объектного поля Ob_Field.
^ Program Compos;
Uses Crt;
Type
OutS = Object {класс Выводимая строка}
S:string; {строка вывода}
Cs:byte; {цвет символов строки}
Procedure Init(Sn:string;Csn:byte); {инициализация полей}
^ Procedure Print; {вывод строки}
End;
Procedure OutS.Init; Begin S:=Sn; Cs:=Csn End;
Procedure OutS.Print; Begin Textcolor(Cs); Write(S) End;
Type
Win = Object {класс Окно}
X1,Y1,X2,Y2, {координаты окна}
Cf:byte; {цвет фона}
Ob_Field : OutS; {статическое объектное поле}
Procedure Init(Xn1,Yn1,Xn2,Yn2,Cfn:byte;Obn:OutS);
Procedure MakeWin; {изображение окна}
^ End;
Procedure Win.Init;
Begin X1:=Xn1; Y1:=Yn1; X2:=Xn2; Y2:=Yn2; Cf:=Cfn;
Ob_Field:=Obn; {инициализация объектного поля }
End;
Procedure Win.MakeWin;
Begin
Window(X1,Y1,X2,Y2); Textbackground(Cf); Clrscr;
Ob_Field.Print; {обращение к методу Print класса OutS как к методу поля класса Win}
End;
Var V:Win; F:OutS; {объявление экземпляров классов}
Begin
F.Init('Объектное поле',1); {инициализировать объекты}
V.Init(20,10,35,10,0,F); {F – параметр-объект}
V.MakeWin; {изобразить окна и вывести строку}
Readkey;
End.
Наполнение отличается от композиции тем, что вместо объектных полей используются поля, содержащие указатели на объекты.
^ Пример 2.28. Использование полей - указателей на объекты
Ниже приведена программа, в которой автоматически генерируется заданное количество окружностей (объектов), перемещающихся по линейному закону в пределах определенной зоны экрана (рис. 2.6).
Рис. 2.39. Вид экрана при выполнении программы «Окружности»
В программе осуществляется анализ на столкновение всех окружностей друг с другом и с зоной. При столкновении окружности меняют направление движения «оттолкнувшись» друг от друга.
Диаграмма объектов для данного примера представлена на рис.2.7.
Рис. 2.40. Диаграмма объектов программы «Окружности»
Для реализации объектов программы потребуются классы: Zona (зона) и Cir (окружность). Класс Zona будет включать поля, определяющие размер зоны на экране, поле N – для хранения количества окружностей и поле P - массив указателей на объекты класса Cir. Он также будет включать методы инициализации Init, изображения зоны Out и перемещения окружностей Run. Удобно определить внутренний метод Control, который будет определять наличие столкновений всех созданных объектов-окружностей друг с другом и зоной (рис.2.8).
Класс Cir существенно проще. Он должен содержать поля, определяющие его местонахождение, радиус и цвет, а также метод перемещения и внутренний метод изображения. Запрос зоны о местоположении окружности можно реализовать простым обращением к соответствующим полям объекта.
Рис. 2.41. Диаграмма классов программы «Окружности»
Рассмотрим работу программы, акцентируя внимание на использовании полей указателей на объекты.
В начале задаются параметры зоны, и определяется количество размещаемых окружностей. Далее инициализируются объекты типа Cir и объект типа Zona. В результате полю P объекта Z будет передан массив указателей на объекты типа Cir.
В методе Control объекта Z отслеживается ситуация возможного столкновения друг с другом всех созданных экземпляров классов. Если прогноз на столкновение каких-либо объектов для следующего шага положительный, то метод Control изменяет направление движения окружностей. Такое управление становится возможным благодаря использованию указателей, переданных объекту типа Zona.
^ Program MoveCir;
Uses graph,crt;
Type
Cp=^Cir; {указатель на класс}
Cir=Object {класс Окружность}
X,Y,R,C, {координаты центра, радиус и цвет окружности}
Dx,Dy:integer; {шаг перемещения}
Constructor Init(Xn,Yn,Rn,Cn,Dxn,Dyn:integer); {конструктор}
^ Procedure Out; {изображение окружности}
Procedure Move; {перемещение окружности}
End;
Constructor Cir.Init;
Begin R:=Rn; C:=Cn; Dx:=Dxn; Dy:=Dyn; X:=Xn; Y:=Yn End;
Procedure Cir.Out;
Begin Setcolor(C); Circle(X,Y,R) End;
Procedure Cir.Move;
Var cc:integer;
Begin cc:=C; C:=Getbkcolor; Out; C:=cc; X:=X+Dx; Y:=Y+Dy; Out;
End;
Type
mascp=array [1..100] of Cp; {массив указателей}
Zona=Object {класс Зона}
X,Y,Lx,Ly, {координаты верхнего левого угла и размеры зоны}
C:word; {цвет зоны}
P:mascp; {поле - массив указателей}
N:byte; {количество окружностей}
Constructor Init(Xn,Yn,Lxn,Lyn,Cn:word;Pn:mascp;Nn:byte);
Procedure Out; {изображение зоны}
^ Procedure Control; {проверка объектов на столкновение}
Procedure Run; {перемещение окружностей}
End;
Constructor Zona.Init;
Begin X:=Xn; Y:=Yn; Lx:=Lxn; Ly:=Lyn; C:=Cn; P:=Pn; N:=Nn End;
Procedure Zona.Out;
Begin Setcolor(C); Rectangle(X,Y,X+Lx,Y+Ly) End;
Procedure Zona.Control;
{Прогноз на столкновение двух окружностей}
^ Procedure CrCr(P1,P2:Cp);
Var wx,wy:real;
Begin wx:=P1^.X+P1^.Dx-P2^.X-P2^.Dx;
wy:=P1^.Y+P1^.Dy-P2^.Y-P2^.Dy;
if (sqrt(sqr(wx)+ sqr(wy)) <= P2^.R+P1^.R) then
begin {смена направления перемещения}
P1^.Dx:=-P1^.Dx; P2^.Dx:=-P2^.Dx;
P1^.Dy:=-P1^.Dy; P2^.Dy:=-P2^.Dy;
end;
End;
{Прогноз на столкновение окружности с зоной}
Procedure CrZn(P:Cp);
Begin
if (P^.X+P^.Dx-P^.R <= X) or (P^.X+P^.Dx+P^.R >= X+Lx)
then P^.Dx:=-P^.Dx; {смена направления движения по X}
if (P^.Y+P^.Dy-P^.R <= Y) or (P^.Y+P^.Dy+P^.R >= Y+Ly)
then P^.Dy:=-P^.Dy; {смена направления движения по Y}
^ End;
Var i,j:integer;
Begin
{Проверка на столкновение всех окружностей друг с другом}
for i:=1 to N-1 do for j:=i to N do CrCr(P[i],P[j]);
{Проверка на столкновение с зоной всех окружностей}
for i:=1 to N do CrZn(P[i]);
End;
Procedure Zona.Run;
Var k:integer;
Begin Control; {вызвать метод проверки на столкновение}
for k:=1 to n do P[k]^.Move;
End;
{ основная программа }
Var Z:Zona; {объект класса Zona}
V:mascp; {массив указателей на класс Окружность}
a,rg,k,d,i, {вспомогательные переменные}
x,y,lx,ly,lmin,cz, {параметры зоны}
n,nmax, {max и текущее количество окружностей}
xc,yc,cc, {координаты центра и цвет окружности}
r,rm, {текущий и максимальный радиус}
dx,dy:integer; {шаг перемещения окружности по осям}
Begin
^ Clrscr; Writeln('Введите:':20);
Write('координату верхнего левого угла зоны по X - '); readln(x);
Write('координату верхнего левого угла зоны по Y - '); readln(y);
Write('размер зоны по оси X - '); readln(lx);
^ Write('размер зоны по оси Y - '); readln(ly);
cz:=random(14)+1; {цвет зоны}
if lx<=ly then lmin:=lx else lmin:=ly;
rm:=random(round(lmin/2))+3; {max радиус}
nmax:=sqr(round(lmin/(2*rm+1))); if nmax>100 then nmax:=100;
Write('количество окружностей (не более ',nmax,' ) - '); readln(n);
^ Write('задержку - '); readln(d);
xc:=x+rm+1; yc:=y+rm+1; k:=n;
while k>0 do
begin {инициализация окружностей}
r:=random(rm)+1; cc:=random(15)+1;
repeat dx:=random(5)-3 until dx<>0;
repeat dy:=random(5)-3 until dy<>0;
if (xc+rm+1) < (x+lx) then
begin New(V[k]); V[k]^.Init(xc,yc,r,cc,dx,dy); {окружности}
dec(k); xc:=xc+2*rm+1
end
else if (yc+rm+1)< (y+ly) then
begin yc:=yc+2*rm+1; xc:=x+rm+1 end;
end;
a:=Detect; Initgraph(a,rg,'C:\TP\BGI');
Z.Init(x,y,lx,ly,cz,V,n); {инициализировать зону}
Z.Out; {отобразить зону}
repeat
Z.Run; {вызвать метод движения окружностей}
for i:=1 to 10 do delay(d);
until Keypressed;
Closegraph;
End.