Рабочая программа по дисциплине Цели и задачи освоения дисциплины Дисциплина Объектноориентированный анализ и программирование
Скачать 339.98 Kb.
|
Инкапсуляция — это еще и языковая конструкция, позволяющая объединять данные с методами, обрабатывающими их. Полиморфизм Третьим принципом объектно-ориентированного программирования является полиморфизм. Под этим термином принято понимать возможность элементов с одинаковой спецификацией иметь различные реализации. Типичным примером полиморфизма является наследование. Если некоторый класс содержит определенный метод, то и его класс-потомок будет содержать аналогичный метод. Его вызов, при условии, что он не переопределен в потомке, будет передан на обработку родительскому классу. Иначе (когда метод переопределен) обработкой будет заниматься класс-потомок. Такой подход позволяет создавать единообразный и простой для понимания программный код со сложным поведением. Можно сказать, что полиморфизм — это существование точек «кастомизации», когда один и тот же код может означать разные операции в зависимости от дополнительных условий. Частным случаем полиморфизма является перегрузка методов. Так называется ситуация, когда класс содержит несколько членов с одинаковым именем, но разной сигнатурой. Тогда выбор конкретной реализации будет зависеть от набора передаваемых параметров. Одним из основных механизмов, лежащих в основе полиморфизма, выступает динамическое связывание. В процедурных языках тело функции связывается с местом ее вызова на этапе компиляции. Такой подход получил название статического (или раннего) связывания. В объектных языках же возможна ситуация, кода указатель на экземпляр класса А на самом деле связан с экземпляром класса В (при этом В является наследником А). Вызов перегруженного метода через указатель должен повлечь работу метода из В, однако компилятору это не известно. Решением проблемы является динамическое (или позднее) связывание, то есть привязка тела метода к месту вызова непосредственно во время выполнения. Наиболее популярным способом организации динамического связывания является аппарат виртуальных функций. Виртуальным называется метод класса, который может быть переопределен в потомке таким образом, что конкретная реализация будет выбираться во время выполнения. Технически работа с виртуальными функциями осуществляется через специальные таблицы. Каждый объект, имеющий хотя бы одну виртуальную функцию, хранит указатель на таблицу своего класса, с помощью которой вычисляется адрес расположения необходимой реализации метода в памяти. Остается добавить, что использование виртуальных функций актуально не для всех языков программирования. Так, например, в Java нет понятия виртуальной функции, а в Python — все методы являются виртуальными. Прочие понятия объектно-ориентированного программирования Абстрактные классы Абстракт ным называется класс, который не может иметь экземпляров. Таким образом, такой класс позволяет перейти на еще более высокий уровень абстрагирования. Обычно они применяются для описания самых общих свойств сущностей. Абстрактный класс, точно также как и обычный класс, может содержать поля и методы. Если метод объявляется как абстрактный, то он обязательно должен быть переопределен в потомке. Некоторые языки программирования допускают наличие в абстрактном классе только абстрактных методов, другие — разрешают не только декларировать, но и реализовывать часть функциональных возможностей непосредственно в абстрактной сущности. Фактически, абстрактные классы реализуют на практике принцип полиморфизма. Также необходимо отметить, что все-таки не существует устоявшегося понятия «абстрактного» класса. Нюансы работы с подобными сущностями тесно связаны с особенностями конкретного языка программирования. Так, например, несмотря на общепринятое определение, в Delphi разрешается создавать экземпляры абстрактных классов, но нс разрешается обращаться к их абст рактным методам. Интерфейсы Альтернативой наследованию являются интерфейсы — семантические и синтаксические конструкции, специфицирующие функциональные возможности, предоставляемые сущностями. Проще говоря, интерфейс — это совокупность сигнатур методов, которые должен реализовывать класс. Данный механизм появился и развивался как способ решения проблем, возникающих при множественном наследовании. В большинстве объектно-ориентированных языков программирования класс, реализующий интерфейс, должен реализовывать все методы объявленные в этом интерфейсе. При этом обращаться к экземпляру класса в таком случае можно по имени интерфейса. Допускается ситуация, когда один класс реализует несколько интерфейсов. В таком случае обращаться к экземпляру можно по имени любого из интерфейсов. Поясним изложенное на примере. Пусть имеется класс WritingTool, абстрагирующее пишущие средства. Любой экземпляр данного класса должен справляться со своей основной функцией — письмом, но писать можно еще, например, и с помощью клавиатуры. Поэтому целесообразно вынесли метод write в отдельный интерфейс Write. Пусть теперь класс WritingTool имеет двух наследников — ручку и карандаш (классы Реп и Pencil). Так как родительский класс реализует соответствующий интерфейс, то и потомки имеют доступ к методу write. От Реп наследуют еще два класса — ChcapPen и ExpcnsivePen (дешевая и дорогая ручка). Они отличаются тем, что дорогая ручка имеет сменные стержни или может быть перезаправлена. Но существуют также и перезаправляемые маркеры. Поэтому данный функционал целесообразно вынести в отдельный WritingToo Pen Pencil Write write CheapPen ExpensivePen Refill refill Пример использования интерфейсов интерфейс Refill. Схематично описанная ситуация представлена на рисунке. Вложенные классы Вложенным классом называется класс, объявленный внутри другого класса. Не стоит путать понятия «вложенный класс» и «класс-член». В первом случае описание класса размещается внутри другого класса, во втором же — внутри класса размещается ссылка на другой класс. Обычно экземпляр вложенного класса может быть создан только внутри класса-хозяина (или управляющего класса). В некотором роде такой подход реализует принцип инкапсуляции — сторонние классы даже не будут знать о существовании вложенного класса. Данный механизм, как правило, применяется в тех случаях, когда необходимо оперировать сущностью только в одном месте, а с точки зрения архитектуры приложения, она не может быть «внедрена» в управляющий класс. Анонимные классы Анонимным называется неименованный класс, то есть такой класс, экземпляр которого создается «здесь и сейчас». Так как подобный класс не имеет имени, то его экземпляр не сможет быть создан в другом участке кода. На самом деле способ создать второй экземпляр класса все же имеется (например, шаблон проектирования «прототип»), но на практике это не нужно (иначе нет смысла создавать анонимный класс вовсе). Чаще всего анонимные классы применяются для создания сущностей с уникальным поведением. Например, при создании графического интерфейса посредством swing часто требуется реализовать уникальный класс для обработки конкретного действия пользователя. В таком случае анонимный класс — наиболее подходящее решение. Пространства имен При разработке сложных программных систем одним из эффективных способов организации кода является группировка элементов в соответствии с их назначением. Как правило, эта задача решается с помощью разделения пространства имен. Пространство имен — это некоторый структурный контейнер, включающий в себя программные единицы. Важной особенностью при этом является тот факт, что единицы, расположенные в одном пространстве имен известны друг другу. Такое разделение бывает полезно в тех случаях, когда проект содержит два или более классов с одним именем и разной функциональностью. При обращении к такому объекту по имени управление будет передано экземпляру класса, расположенному в том пространстве имен, из которого был выполнен вызов. Доступ к классу с аналогичным названием в другом пространстве возможен только при явном указании имени этого пространства. Типичными для современных языков уровнями иерархии пространств имен являются блок кода, метод, класс, модуль (пакет) и глобальное адресное пространство. Контрольные вопросы по Теме 1 В чем отличие между классом и объектом? Что понимается под членами класса? Как Вы понимаете термины «наследование», «инкапсуляция», «полиморфизм»? Как называется механизм, используемый для ограничения доступа к членам класса? На чем основана его работа? Что такое «перегрузка» методов? Чем отличаются раннее и позднее связывания? Как с технической точки зрения работает механизм виртуальных функций? В чем отличие абстрактного класса от интерфейса? В чем отличие вложенного класса от анонимного? Как Вы понимаете термин «пространство имен»? Выводы после Темы 1 Центральными понятиями объектно-ориентированного программирования являются класс и объект. Класс — «чертеж», который описывает некоторую абстрактную сущность. Объект — конкретный экземпляр класса в памяти ЭВМ. Три базовых принципа объектно-ориентированного программирования: Наследование — класс может передать свои свойства и методы «по цепочке» следующему, расширяющему функционал, классу. Инкапсуляция — ни один класс не должен иметь доступа к «лишней» информации. Полиморфизм — один интерфейс, множество реализаций. Интерфейс — альтернатива множественному наследованию. Тема 2. «Язык графического описания UML» Управление процессом разработки любой программной системы осуществляется на основании подготовленной на этапе проектирования документации. Известно, что подробное описание программной архитектуры даже начального уровня сложности, как правило, занимает более сотни страниц. Такой объем информации сказывается на восприятии непосредственным реализатором (программистом) задумок архитектора, что значительно увеличивает сроки разработки. В связи с этим в середине 80-ых годов прошлого века назрела серьезная проблема — используемые методологии проектирования не справлялись с возрастающей сложностью систем, сопутствующие разработке процессы замедлялись, весь процесс создания программных продуктов становился затянутым и менее гибким. Все эти факты привели к осознанию потребности в едином, простом для восприятия языке описания программных продуктов. Обобщение наиболее популярных на тот момент времени методологий (Booch, Object-Oriented Software Engineering, Object Modeling Technique) привело к созданию языка моделирования UML (Unified Modeling Language), первоочередной целью которого было упрощение и унификация процесса проектирования. История развития языка UML Резкое увеличение числа методов объектно-ориентированного проектирования и анализа при по прежнему острой неудовлетворенности разработчиков ПО их возможностями привело к осознанию необходимости создания единого и общепринятого метода проектирования. Разработка средства, получившего название UML, велась в лаборатории компании Rational Software. Первая версия (0.8) языка моделирования UML была выпущена спустя приблизительно год после начала сотрудничества Г. Буча и Д. Рамбо (авторов методологий проектирования OODA и ОМТ соответственно, сотрудников Rational Software), в 1995 году. Осенью 1995 года к разработке подключился автор метода OOSE И. Якобсон. Каждая из методологий, положенных в основу UML обладала своими достоинсвами и недостатками: OODA (Booch) была прежде всего ориентирована на дизайн программных систем, но не предоставляла инструментов для их анализа; ОМТ включала инструментарий для анализа, но была практически непригодна для проектирования сложных систем; OOSE применялась прежде всего в тех случаях, когда приоритетным являлось требование анализа поведения систем. UML объединил преимущества наиболее популярных подходов проектирования своего времени и нивелировал их недостатки, в следствии чего эта новая методология практически сразу же стала стандартом «де-факто» в области описания архитектур программных систем. В результате растущего интереса к UML ведущая роль в разработке в 1996 году перешла к консорциуму OMG (Object Managment Group). В этом же году были выпущены версии 0.9 и 0.91. С 1997 года к разработке стандарта стали подключаться такие крупные корпорации как Microsoft, Hewlett-Packard, IBM и Oracle Corporation. Итогом совместной работы гигантов программной индустрии стали спецификации UML версии 1.0 и 1.1. Версии 1.3, 1.4 и 1.5 были выпущены в период с 1999 по 2003 годы. Улучшения в основном касались описательных возможностей нотации UML. В 2005 году был выпущен расширенный и дополненный стандарт UML 2.0. Последней версией на сегодняшний день является стандарт 2.4. Структура UML Унифицированный язык моделирования UML предназначен для описания программных систем. Создатели данного инструмента преследовали три цели: разработать средство для спецификации ПО любого уровня сложности (от простого графического или консольного приложения до web-сервера с обработкой запросов в реальном времени), проассоциировать данное средство с реальными языками программирования и предоставить простой способ для создания документации на ПО. Таким образом, сами авторы определили UML как средство для специфицирования, конструирования и документирования ПО. Однако разработанное средство получилось настолько удачным, что оказалось пригодно для спецификации, описания и анализа не только программных систем, но и практически любых объектов и процессов. Так, например, UML широко применяется для описания бизнес-процессов. Стандарт UML использует графические элементы (диаграммы) для отображения информации о моделируемом объекте. Диаграмма представляет собой набор вершин и дуг, объединяющих их. Вершины также называются сущностями, а дуги — связями. Выделяют четыре типа сущностей (структурные, поведенческие, группирующие и аннотирующие) и четыре типа связей (зависимость, ассоциация, обобщение и релизация). Хотя некоторые из них и будут рассмотрены в следующем разделе, тем не менее крайне рекомендуется обратиться за дополнительной информацией к первоисточнику — книге Г. Буча, Д. Рамбо и И. Якобсона «Язык UML. Руководство пользователя». Каждая диаграмма является или структурной (описывают сущности), или поведенческой (описывают деятельности). Основные типы диаграмм с их краткой характеристикой перечислены ниже. Диаграмма классов (class diagram). Предназначена для изображения структур классов и их взаимосвязей. Подробно будет рассмотрена ниже. |