Объектно-ориентированное программирование

Страницы работы

Содержание работы

Объектно-ориентированное программирование

Абстрактные данные

Под абстрактным типом данных понимают такую программную модель, которая определяет набор допустимых значений рассматриваемого типа данных и набор допустимых операций, производимых с этим типом. В модуле описания (definition module) задаются имена абстрактных типов и перечень их процедур с описанием типов и количества параметров. В модуле реализации (implementation module) даны тела процедур, обрабатывающих лежащие в основе типы данных. Это разделение явилось значительным продвижением в технологии разработки ПО, так как доступ к внутренней структуре данных стал возможен только с помощью перечисленного в фазе описания набора процедур. При этом большинство ошибок в обработке данных определенного типа выявляется на этапе компиляции, что повышает надежность создаваемого ПО. Введем два базовых понятия, которые играют существенную роль в ООП:

¨  Инкапсуляция — это связывание определенного типа данных с набором процедур и функций, используемых для манипуляции этими данными. По сути это объединение (помещение в одну капсулу, класс) как данных, характеризующих все объекты определенного класса, так и функций, с помощью которых эти данные обрабатываются.

¨  Скрытие данных — это запрет на доступ к внутренней структуре данных напрямую, минуя специально созданные для этого процедуры (методы).

Использование инкапсуляции и скрытия данных позволяют программистам избежать многих проблем в сопровождении ПО. Если меняется структура ключевых данных, то изменению подлежит лишь небольшая и расположенная в одном месте часть программы, расположенная в модуле реализации (implementation module). Остальная часть системы ПО остается без изменений, так как она связывается с ключевыми данными только через процедуры, обозначенные в definition module. Объектно-ориентированные языки (Smalltalk, C++, Java) делают акцент не на передачу данных процедурам, а на посылку сообщений объектам определенного класса.

Понятие класса в С++

В ООП каждый объект принадлежит определенному классу. Класс — это основной инструмент, посредством которого осуществляется инкапсуляция и скрытие данных. Если описан класс, то определены характеристики всех объектов, принадлежащих этому классу. Функции, инкапсулированные в классе и предназначенные для выполнения каких-либо операций с данными любого из объектов этого класса принято называть методами класса. Начнем рассмотрение класса со структуры (struct), которая в С++ является частным случаем класса. В отличие от языка С структура в С++ может содержать не только данные, но и методы. Данные и методы, описанные внутри структуры, по умолчанию являются доступными извне. В применении к данным или методам класса описатель public означает их доступность извне. Он в некотором смысле противоположен описателю private, который обозначает скрытые, недоступные извне данные и методы. Для структуры описатель public принят по умолчанию. При этом отсутствует скрытие данных, но есть инкапсуляция. В общем случае при объявлении класса в нем могут быть инкапсулированы данные и методы как доступные, так и недоступные извне. Для обеспечения доступности члены класса должны располагаться под влиянием описателя public, или по другому, находиться в секции public.

В качестве примера рассмотрим описание структуры, которая объединяет минимальный набор данных, характеризующий абстрактного человека. Для этого зададим имя типа структуры, например, Man. Выберем поля данных, характеризующих абстрактного человека, то есть любого представителя класса (структуры) Man. Пусть это будут: имя (char* Name) и возраст (uint Age). Дополним структуру функциями (методами), позволяющими производить манипуляции с объектами типа Man. Минимальный набор методов, очевидно, должен позволять вводить и выводить данные, характеризующие человека. Пусть метод void in(); служит для ввода данных структуры, а метод void out(); — для вывода.

struct Man             // Тип структуры

{

char* name;           // Поля данных

int age;

void In ()  // Метод (функция) ввода

{        

  char buf[256];

puts ("\n\tType Man\n Name: ");

  gets (buf);

  name = strcpy (new char[strlen(buf) + 1], buf);

  puts ("\n Age: ");

  scanf ("%d", &age);

}

void Out () { printf ("\n %s,\t Age:%d",Name,Age); } // Метод (функция) вывода

};

void main()//=== Демонстрация использования структуры

{

Man m;              // Объект m типа Man

m.In();   m.Out();  // Ввод, вывод данных

m.age = -2000;      // Доступ к полю данных (извне)

m.Out();            // Поле искажено

}

В ООП, наряду с вызовами обычных внешних функций, принято говорить о передаче сообщений объектам классов. Сообщением считается имя того или иного метода . Методом принято называть функцию - член класса в отличии от обычной внешней функции. В нашем примере внутри функции main объявлен объект (структура) m типа Man, который имеет весь набор полей, присущих любой структуре типа Man. В main демонстрируется как происходит передача сообщения объекту. Так, запись m.In(); означает, что структуре m типа Man передается сообщение In(), которое является именем метода, определенного, а, следовательно, и легального для структур типа Man.

Внутри метода In данные класса доступны прямо и могут быть модифицированы. Причем эти данные принадлежат тому объекту (представителю) класса, которому было послано сообщение. Метод позволяет изменить значение данных структуры m. В то же время любое поле этой структуры может быть изменено обычным для структуры способом простого присвоения, как это сделано в операторе m.Age = -2000;. Отметим, что если в функции main пользоваться указателем на объект класса (например,), то присвоение должно выглядеть так:

Man *p = new Man;

p->age = -2000;

Вместо символа точка необходимо использовать другую операцию выбора — два символа (минус и больше), образующие стрелку-указание на объект. Рассмотренный метод обращения к функции на первый взгляд кажется просто вычурным способом производить по смыслу те же действия, что и в структурном подходе. Однако, мы еще ничего не успели показать из преимуществ ООП. В примере продемонстрировано использование только одной концепции ООП, а именно: инкапсуляции. В одну капсулу — тип структур Man — заключены данные: char* name; int age; и функции (методы): void In(); void Out();.

Как функции — члены структуры Man, так и ее данные, доступны внутри функции main. Они также были бы доступны внутри любой другой обычной функции, которая могла бы быть создана и быть в той же области видимости. Здесь нет скрытия данных. Оператор m.Age = -2000; демонстрирует, как намеренно или по ошибке можно изменить содержимое поля объекта (структуры) m. Этот вариант доступа к полю возможен потому, что все данные структуры по умолчанию имеют тип public, что означает их доступность непосредственно из любой функции, где объявлена и действует структура типа Man. Заметим, что поле age структуры m принимает недопустимое значение и эту ошибку компилятор, конечно же, не видит. Именно этого стремились избежать, создавая концепцию ООП. В приведенном примере не использована возможность скрытия данных, которая является выражением второго базового понятия ООП. Теперь рассмотрим, как следует поступать в соответствии с концепцией ООП. Определим класс и заставим работать в нашу пользу скрытие данных, осуществлямое в его рамках.

Похожие материалы

Информация о работе