bigpo.ru | ![]() |
1 2 3 ... 7 8 Системы программирования, поддерживающие об’ектно-ориентированную разработку. Принципы об’ектно-ориентированного программирования. Проектирование (декомпозиция) – разбиение системы на подсистемы. Нас интересует об’ектная декомпозиция, то есть статическая структура системы – об’екты и связи между ними, а динамическое поведение системы – обмен сообщениями между об’ектами. В 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() содержится слово |
![]() |