bigpo.ru
добавить свой файл
  1 2 3 ... 7 8
ЧАСТЬ I

Системы программирования, поддерживающие об’ектно-ориентированную разработку. Принципы об’ектно-ориентированного программирования.

Проектирование (декомпозиция) – разбиение системы на подсистемы.

Нас интересует об’ектная декомпозиция, то есть статическая структура системы – об’екты и связи между ними, а динамическое поведение системы – обмен сообщениями между об’ектами. В C++ обмен сообщениями представлен набором методов об’екта, которые можно вызывать из других об’ектов.


Основные принципы обектной модели:

  • абстракция и инкапсуляция

  • наследование

  • полиморфизм

Абстракция – приём борьбы со сложностью. В предметной области необходимо выявить об’екты, выделить нужные нам свойства, то есть создать модель предметной области.

Инкапсуляция – средство, позволяющее спрятать реализацию и показывать пользователю только интерфейс абстракции (возможности взаимодействия с другими абстракциями).

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

Полиморфизм различают статический, динамический и типовой (параметрический).

Статический полиморфизм – возможность иметь несколько функций с одинаковыми именами, но разными профилями (выбор осуществляется по списку параметров во время компиляции) – в C++ это overloading (перегрузка).

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

Типовой (параметрический) полиморфизм (шаблоны функций/классов) – возможность настройки абстракции на конкретный тип данных. Обработка состоит из двух этапов: настройка на типовой параметр и вызов этой функции, уже настроенной на тип. Например, при описании класса, реализующего стек, мы не знаем, какой тип элементов захочет использовать юзер (юзер – это программист! Проще: не хотим привязываться к конкретному типу элементов, чтобы не реализовывать два разных стека для, скажем, целых и вещественных чисел – Д.Ч.).

Следует различать понятия об’ектного языка и об’ектно-ориентированного языка.

Об’ектный язык – язык, который поддерживает все принципы ООП, за исключением наследования. Например, такими были языки Simula ’67, ADA’85.

Об’ектно-ориентированный язык – язык, поддерживающий все принципы ООП. Например, C++, Java, Eiffel, Object Pascal и другие.


Об’ектно-ориентированное проектирование.

Мы должны научиться выделять об’екты и конкретизировать их состояние и поведение. При анализе существительные переходят в об’екты. Например, при описании банкомата об’ектами будут сам банкомат, счёт, банк и т.д. При этом следует следить за отсутствием избыточности (грубо говоря, в списке об’ектов не должно быть синонимов). Свойства об’ектов не должны быть об’ектами, например, деньги – не самостоятельный об’ект, а свойство счёта. Операции с об’ектом также не являются об’ектами. Возникает проблема, на каком этапе надо задумываться об об’ектах, которых нет в предметной области, но которые нужны для реализации? Существуют разные мнения на эту тему: либо на этапе проектирования, либо отложить их до кодирования. Например, таким об’ектом является очередь клиентов при доступе к счетам.

Пример. Моделирование предметной области для банковской сети.

Выделяем следующие абстракции – об’екты предметной области:

  • баксомёт

  • клиент

  • карта

  • счёт

Диаграмма нарисована в стиле UML-карточки. Вверху пишется имя об’екта, во второй части его свойства – атрибуты, в третьей – методы – характеристики его поведения.

Далее нужно проанализировать инкапсуляцию. Обычно прячут всё, что возможно, так как другие об’екты не должны знать, как функционирует об’ект, а только его интерфейс. В большинстве случаев, свойства прячут, а методы открывают. В диаграмме ‘-‘ означает права доступа private, ’+’ – public, а ‘#’ – protected.

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


Некоторые особенности языка C++.

В C++, в отличие от C, в функцию можно передавать параметры по ссылке, примерно как в Pascal. Например, в C мы бы написали

void swap (int *x, int *y){

int t; t = *x; *x = *y; *y = t;

}

А в теле программы вызывали бы int a, b; ... swap (&a,&b);

А на плюсах можно написать и так:

void swap (int &x, int &y){

int t; t = x; x = y; y = t;

}

И тогда вызывать swap (a,b);

Для работы с динамической памятью в C использовались функции malloc, calloc, realloc и free. В C++ есть операции new и delete, которые призваны заменить их, хотя по-старому писать, конечно, тоже можно. Используют их примерно так:

int *p;

p = new int; // вместо p = (int*) malloc (sizeof(int))

*p = 5;

// работа с p

delete p;

В случае если надо запросить память под массив, действуют так:

int *p = new int[10]; //вместо p = (int*)malloc(10*sizeof(int))

// работа с p

delete[] p;

Классы, специальные функции-члены класса.

Классы бывают плоскими и не плоскими. Плоским принято считать класс, который не содержит указателей.

Конструктор класса – специальная функция-член класса, с помощью которой создаётся об’ект, имя которой совпадает с именем класса, и не возвращающая никакого значения. Любой класс содержит конструкторы, по дефолту есть два конструктора – умолчания и копирования.

Конструктор умолчания – конструктор вида X (); Впрочем, параметры могут присутствовать, но для них всех должны быть заданы значения по умолчанию, поэтому точное определение такое: конструктор, который может быть вызван без параметров. Если в классе явно определён хотя бы один конструктор, конструктор умолчания автоматически не создаётся!

Конструктор копирования – конструктор вида X (const X&); который служит для инициализации об’екта другим об’ектом. Дополнительно могут быть параметры кроме первого, но для них должны быть заданы умолчания. При неиспользовании const в определении типа аргумента могут возникнуть проблемы при инициализации об’екта определяемого класса константным об’ектом. (Было написано все наоборот!! - Д.Ч.)

Обычные конструкторыконструкторы, у которых есть параметры, не все из них имеют значения по умолчанию, и первый из них не const X&. Такой конструктор вызывается при создании об’екта (что-нить типа X a (3,5);) или при создании об’екта в динамической памяти (X *p; p = new X (3,5); - тут происходит сначала заказ памяти по new, а потом вызывается конструктор об’екта p*), а также в некоторых других случаях, которые будут рассмотрены позднее.

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

~X () {}

Пример. Описание класса комплексных чисел.

Вывод на консоль обычно осуществляется в C++ через поток cout. Для его использования надо подключить заголовочный файл iostream.

class Complex{

double re, im;

public:

void print() const{ // печать числа в алгебраической форме

cout<

}

}

В секцию private попадают имена, которые не видны извне, соответственно, в секцию public – интерфейс класса. По умолчанию, сначала идут скрытые члены класса. Модификатор устанавливает права доступа вниз полям и методам до следующего модификатора или конца класса. В структурах, наоборот – по умолчанию идут общедоступные члены. В остальном, конструкции class и struct совпадают.

Создание об’екта:

Complex a;

Компилятор отведёт автоматическую память под об’ект, вызывается конструктор умолчания.

В об’явлении функции print() содержится слово

<< предыдущая страница   следующая страница >>