Занятие 13. Объектно-ориентированный подход (ООП) в программировании

Основные понятия ООП

В настоящее время большое распространение получила технология объектно-ориентированного программирования, у истоков которой стоят такие известные специалисты как Гради Буч, признанный эксперт в этой области.

Этот подход к программированию возник, когда появилось понимание того, что программный код тесно связан с теми данными, которые он обрабатывает. Кроме того, упаковка программного кода в объекты, позволяет посмотреть на программу не как на совокупность программного кода, в виде процедур, функций, и данных, а как на взаимодействие различных объектов, каждый из которых представляет собой совокупность программного кода и данных. Такое понимание программы ближе к представлению предметной области в виде объектов реального мира.

Ключевыми понятиями этой технологии являются понятия объекта и класса. Под классом понимается некая совокупность объектов реального мира, обладающих общими свойствами и общим поведением. Например, класс «Собаки» - объединяет вообще всех собак. Класс «Книги» - объединяет все книги. Класс «Студенты» - объединяет вообще всех студентов. Класс «Планеты» - объединяет все планеты, например, солнечной системы.

Объект представляет собой конкретный экземпляр какого-либо класса, например, собака «Шарик» является объектом класса «Собаки», книга «Три мушкетера» - это объект класса «Книги», а студент Иванов Вася является объектом класса «Студенты», планета «Земля» - объект класса «Планеты».

При описании класса задаются свойства объектов класса и их поведение. Свойства могут задавать внешний вид объекта, его состояние и описываются как данные. Поведение объектов задается с помощью программного кода. При этом разные объекты класса могут иметь разные свойства, но одно и то же поведение. Например, разные планеты солнечной системы могут иметь разное положение на экране, разную окраску, разный размер, но движутся они по одним и тем же законам.

Основные принципы ООП

Объект это нечто, что объединяет в себе данные и программный код. Данные реализованы в виде свойств объекта, программный код это методы объекта. Данные у разных объектов могут различаться, но методы у объектов одного класса едины.

Класс это шаблон, тип, в соответствии с которым строятся конкретные экземпляры объектов класса. Данные объекта должны быть защищены своими методами, т.е. доступ к данным объекта должен осуществляться только через методы объекта. Это первый принцип объектно-ориентрованного программирования, который называется – инкапсуляция. Т.е. данные объекта находятся как бы в капсуле из методов объекта. Этот принцип часто называют сокрытие данных.

Можно создавать наследников класса, при этом наследуются все свойства и методы предка и добавляются свои свойства и методы. Этот принцип носит название – наследование. Это очень мощный принцип, который позволяет не изобретать велосипед, а взять все, что нужно у предка и добавить новое.

Тритий принцип ООП называется – полиморфизм ( поли – много, морф – форма), можно перевести как разнообразие. Этот принцип означает, что родственные объекты могут выполнять схожие по смыслу действия разными способами. Т.е. у потомков поведение уже может быть изменено. Иногда этот принцип называют сокрытие интерфейса, т.е. за одним и тем же заголовком метода, реализующего поведение объекта, скрывается разная реализация метода у предка и у потомка. Чтобы было понятно, рассмотрим такой пример. У класса «Транспортное средство» есть метод «Двигаться». Наследниками этого класса являются классы «Автомобиль», «Самолет» и «Пароход». Наследники наследуют у предка все, в том числе и метод «Двигаться». Для класса «Самолет» двигаться – означает летать, для класса «Пароход» двигаться – означает плыть, для «Автомобиля» двигаться означает ехать. Поэтому в каждом классе наследнике метод «Двигаться» получит свою реализацию.

 
  Занятие 13. Объектно-ориентированный подход (ООП) в программировании - student2.ru

Перед тем, как перейти непосредственно к описанию синтаксиса классов и объектов в Delphi, полезно будет познакомиться с еще одним типом данных – комбинированным типом или записью.

Тип данных запись (структура)

При описании конкретного человека требуется иметь информацию о его фамилии, имени, годе рождения, поле. Для описания, например, книги, необходима информация о названии книги, авторе, годе издания. Для описания таких данных используется специальный тип данных – запись, который также называют комбинированный тип. Тип данных запись позволяет задавать набор разнородных, но логически связанных данных. Данные, входящие в состав записи, называют полями записи.

Пример объявления типа записи Planet, который описывает данные о планете:

type

Planet = record

Name:string; {название планеты}

x, y:integer; {экранные координаты планеты}

clr:TСolor; {цвет планеты}

rad:integer; {радиус планеты }

end;

Где ключевое слово type задает описание нового типа.

Planet – имя типа;

Name, x,y, clr, rad - это поля типа, каждое из которых описывается со своим типом.

Следующее объявление задает две переменных типа Planet – Earth(Земля) и Mars(Марс).

var

Earth, Mars: Planet;

Доступ к элементам (полям) записи осуществляется с помощью конструкции, называемой "селектор записи", и имеющей следующий общий вид:

R.F

где R – переменная комбинированного типа (запись), F - имя поля.

Пример:

Earth.Name:='Земля';

Mars.Name:='Марс';

Задание для самостоятельной работы

1. Опишите с помощью типа запись данные о книге: название, автор, год издания, цена. Создайте переменную этого типа и присвойте ей значения.

2. Опишите с помощью типа запись данные об учащемся: фамилия, имя, отчество, дата рождения, класс, информация о родителях. Создайте переменную этого типа и присвойте ей значение.

Классы и объекты в Delphi

Грубо говоря, классы можно рассматривать как расширение понятия структура. Поля объекта аналогичны полям записи. Отличие между полями записей и классов состоит в том, что поля записи общедоступны, а поля класса могут иметь разные уровни доступа. Наряду с дан­ными, класс содержит методы. Методы это процедуры или функции. Класс позволяет описать объекты. Объект в Delphi состоит из полей, свойств и методов. Свойства объекта это поля, защищенные своими методами, т.е. доступ к свойству осуществляется не напрямую, а только через методы объекта. Свойство в Delphi описывается как поле, плюс два метода. Один метод позволяет писать в поле, а другой метод – позволяет читать из поля. Таким образом, в Delphi реализован принцип инкапсуляции.

Покажем использование классов, объектов и основных принципов объектно-ориен­тированного программи­рования на следующем примере. Например, мы хотим изобра­зить на экране движение планет вокруг Солнца. Внешний вид окна может быть таким:

Занятие 13. Объектно-ориентированный подход (ООП) в программировании - student2.ru

Перед тем как писать классы их необходимо спроектировать, а затем оформить в виде операторов языка. В данном примере легко просматриваются следующие классы:

1. Класс «Звезда»;

2. Класс «Планета».

Причем класс «Планета» является наследником класса «Звезда».

 
  Занятие 13. Объектно-ориентированный подход (ООП) в программировании - student2.ru

У класса «Звезда» могут быть следующие поля и методы:

Поля Описание
X,Y Экранные координаты
CLR Цвет звезды
RP Радиус звезды
Метод Описание
DRAW Нарисовать звезду
CLEAN Стереть звезду
MOVE Переместить звезду

Для рисования звезды на экране необходим метод Draw, который, используя экранные координаты звезды, рисует ее в нужном месте. Если звезда, находясь в центре экрана, будет неподвижна, тогда зачем же нам методы Clean и Move, которые используются для создания иллюзии движения объекта? Дело в том, что мы будем проектировать класс «Звезда» так, чтобы можно было от него создать наследника, класс «Планета», который унаследует все поля, свойства и методы предка, добавит новые поля и свойства, а некоторые методы предка будут переопределены в потомке. Т.е. методы Clean и Move только объявляются в классе «Звезда», а реализацию они получат в потомке, т.е. будут переопределены, в классе «Планета».

У класса «Звезда» будет только один экземпляр – это «Солнце».

Перейдем к проектированию класса «Планета». Так как класс «Планета» является наследником класса «Звезда», он наследует все поля и свойства у предка и добавляет свои поля и свойства. В таблице показаны поля класса «Планета», которые будут добавлены:

Поля Описание
RORB Радиус орбиты планеты при движении вокруг звезды
D_UG Угол поворота планеты при движении по орбите, фактически скорость движения планеты по орбите
UGOL Задает начальный угол
K Коэффициент растяжения орбиты по оси X

Заголовки методов у класса «Планета» те же, что и у класса «Звезда». Но метод Draw будет переопределен в классе «Планета», а методы Clean и Move должны получить реализацию.

У класса «Планета» может быть несколько экземпляров: «Земля», «Марс», «Юпитер» и др.

После проектирования можно описать классы с помощью операторов языка. Классы можно описать либо в секции interface, либо на верхнем уровне секции реализации (implementation). Например, класс «Звезда» может иметь следующее описание:

type

TStar = class(TObject)

private

x,y:integer;

col:TColor; // цвет

rp:integer; // радиус планеты

public

constructor Create(x1,y1:integer; col1:TColor; rp1:integer);

procedure draw; virtual;

procedure move; virtual; abstract;

procedure clean; virtual; abstract;

end;

Где ключевое слово type – задает описание класса. TStar – это имя класса. В Delphi имя класса принято начинать с буквы T, что означает type. Ключевое слово class – говорит о том, что описываемый тип – это класс. В скобках задается имя класса, от которого наследуется данный класс. В Delphi все классы являются наследниками класса TObject. Поэтому записи TStar = class(TObject) и TStar = class – равнозначны.

Ключевое слово private – задает скрытые части класса. Доступ к скрытым частям возможен только в рамках данной программной единицы, т.е. того модуля, где содержится описанный класс.

Все методы класса описаны как public(общедоступные), т.е. видимые другими классами.

Ключевое слово virtual, которое используется при описании методов, говорит о том, что данный метод является виртуальным, т.е. этот метод получит другую реализацию у потомков.

Ключевое слово abstract, которое задается при описании методов Clean и Move, говорит о том, что данный метод является абстрактным, т.е. он только объявлен, но не имеет реализации, реализация появится у потомков.

Метод класса Constructor позволяет создать экземпляр класса, т.е. объект, и заполнить значениями его поля. На вход методу поступают значения, которые должны быть присвоены его полям.

Класс «Планета» может иметь следующее описание:

TPlanet=class(TStar)

private

rorb:integer; // радиус орбиты

d_ug:real; // угол поворота

ugol:real; // начальный угол

k:real; // коэффициент растяжения по X

public

constructor CreatePlanet(x1,y1:integer; col1:TColor; rp1:integer;

rorb1:integer; d_ug1,ugol1,k1:real);

procedure clean; override;

procedure draw;override;

procedure move;override;

end;

В части private описываются скрытые части класса – поля, которые добавляются у потомка. В части public описываются общедоступные части класса. Метод CreatePlanet – это конструктор, который позволяет создать экземпляр класса и присвоить начальные значения его полям. Остальные методы описываются с ключевым словом override, которое говорит о том, что данные методы переопределяются в потомке, т.е. получают другую реализацию.

Обратите внимание, при описании классов описываются только заголовки методов. Необходимо еще для каждого метода написать реализацию. Реализация методов задается в части implementation модуля.

Для класса TStar реализация методов имеет следующий вид:

// Конструктор

constructor TStar.Create(x1,y1:integer; col1:TColor; rp1:integer);

begin

x:=x1;

y:=y1;

col:=col1;

rp:=rp1;

end;

// Метод Draw

procedure TStar.Draw;

begin

with form1.canvas do

begin

pen.color:=clBlack;

brush.Color:=col;

ellipse(x-rp,y-rp,x+rp,y+rp);

end;

end;

Для класса TPlanet реализация методов может иметь следующий вид:

// Конструктор

constructor TPlanet.CreatePlanet(x1,y1:integer; col1:TColor; rp1:integer;

rorb1:integer; d_ug1,ugol1,k1:real);

begin

x:=x1; y:=y1; col:=col1; rp:=rp1; rorb:=rorb1; d_ug:=d_ug1; ugol:=ugol1;

k:=k1;

end;

// Метод Draw

procedure TPlanet.draw;

begin

with form1.canvas do

begin

pen.color:=clBlack;

brush.Color:=col;

ellipse(x-rp,y-rp,x+rp,y+rp);

end;

end;

// Метод Clean

procedure TPlanet.clean;

begin

with form1.Canvas do

begin

pen.color:=fon;

brush.Color:=fon;

ellipse(x-rp,y-rp,x+rp,y+rp);

end;

end;

// Метод Move

procedure TPlanet.move;

var x0,y0:integer;

begin

ugol:=ugol+d_ug;

x0:=Form1.width div 2;

y0:=Form1.height div 2;

x:=x0+round(k*rorb*cos(ugol));

y:=y0-round(rorb*sin(ugol));

end;

После описания классов необходимо объявить переменные классов TStar и TPlanet. Это можно сделать либо в секции interface, либо на верхнем уровне секции реализации:

var

Sun:TStar; // переменная-указатель на объект класса TStar

Earth, Mars : TPlanet; // переменные-указатели на объекты класса TPlanet.

Переменная-указатель будет содержать адрес объекта, она только указывает на объект, но объекта еще нет, его нужно создать. Для создания объектов можно использовать событие формы OnCreate. Объекты создаются с помощью конструкторов и для свойств объектов назначаются начальные значения. Обработчик события OnCreate формы может иметь следующий вид:

procedure TForm1.FormCreate(Sender: TObject);

var x1,y1:integer;

begin

randomize;

x1:=Form1.Width div 2;

y1:=Form1.Height div 2;

// Создание объекта класса TStar

Sun:=TStar.Create(x1,y1,clYellow,10);

// Создание объекта Earth

x1:=Form1.Width div 2+round(1.3*20);

y1:=Form1.Height div 2;

Earth:=TPlanet.CreatePlanet(x1,y1,clBlue,5,20, 2*pi/100, 0,1.3);

// Создание объекта Mars

x1:=Form1.Width div 2+round(1.3*60);

y1:=Form1.Height div 2+round(60);

Mars:=TPlanet.CreatePlanet(x1,y1,clRed,3,60,2*pi/70,2,1.3);

end;

Для организации движения поместим в область формы компонент Timer1:TTimer. На событие OnTimer этого компонента напишем обработчик:

procedure TForm1.Timer1Timer(Sender: TObject);

begin

// рисуем планеты в движении

with Earth do begin

clean;

move;

draw;

end;

with Mars do begin

clean;

move;

draw;

end;

end;

Задание для самостоятельной работы

Добавьте еще несколько планет в нашу солнечную систему.

Контрольные вопросы

1. Какие данные позволяет описать тип данных запись?

2. Что такое класс? Что такое объект?

3. Из каких основных элементов состоит объект в Delphi?

4. Чем поля объекта отличаются от полей записи?

5. Что такое свойство и чем оно отличается от поля?

6. Как реализованы методы объектов в Delphi?

7. Перечислите основные принципы объектно-ориентированного програм­миро­ва­ния.

8. Что такое инкапсуляция? Как в Delphi реализована инкапсуляция?

9. Что такое наследование? Какой объект в Delphi является общим предком всех объектов?

10. Что такое полиморфизм?

Наши рекомендации