Автор работы: Пользователь скрыл имя, 05 Октября 2015 в 15:52, реферат
Краткое описание
ООП возникло в результате развития идеологии процедурного программирования, где данные и подпрограммы (процедуры, функции) их обработки формально не связаны. Для дальнейшего развития объектно-ориентированного программирования часто большое значение имеют понятия события (так называемое событийно-ориентированное программирование) и компонента (компонентное программирование, КОП).
Содержание
1. Введение 2. Основные понятия 3. Определение ООП и его основные концепции 3.1 Сложности определения 3.2 Концепции 4. Особенности реализации 5. Подходы к проектированию программ в целом 6. Родственные методологии 6.1 Компонентное программирование 6.2 Прототипное программирование 6.3 Класс-ориентированное программирование 7 . Производительность объектных программ 8. Критика ООП 9. Объектно-ориентированные языки Заключение Литература
Интерфейс — это класс без полей и
без реализации, включающий только заголовки
методов. Если некий класс наследует (или,
как говорят, реализует) интерфейс, он
должен реализовать все входящие в него
методы. Использование интерфейсов предоставляет
относительно дешёвую альтернативу множественному
наследованию.
Взаимодействие объектов в абсолютном
большинстве случаев обеспечивается вызовом
ими методов друг друга.
Инкапсуляция обеспечивается
следующими средствами
Контроль доступа
Поскольку методы класса могут
быть как чисто внутренними, обеспечивающими
логику функционирования объекта, так
и внешними, с помощью которых взаимодействуют
объекты, необходимо обеспечить скрытость
первых при доступности извне вторых.
Для этого в языки вводятся специальные
синтаксические конструкции, явно задающие
область видимости каждого члена класса.
Традиционно это модификаторы public, protected и private, обозначающие, соответственно, открытые члены класса, члены класса, доступные только из классов-потомков и скрытые, доступные только внутри класса. Конкретная номенклатура модификаторов и их точный смысл различаются в разных языках.
Методы доступа
Поля класса, в общем случае,
не должны быть доступны извне, поскольку
такой доступ позволил бы произвольным
образом менять внутреннее состояние
объектов. Поэтому поля обычно объявляются
скрытыми (либо язык в принципе не позволяет
обращаться к полям класса извне), а для
доступа к находящимся в полях данным
используются специальные методы, называемые
методами доступа. Такие методы либо возвращают
значение того или иного поля, либо производят
запись в это поле нового значения. При
записи метод доступа может проконтролировать
допустимость записываемого значения
и, при необходимости, произвести другие
манипуляции с данными объекта, чтобы
они остались корректными (внутренне согласованными).
Методы доступа называют ещё аксессорами (от англ. access — доступ), а по отдельности — геттерами (англ. get —
чтение) и сеттерами (англ. set —
запись)[2].
Свойства объекта
Псевдополя, доступные для чтения и/или записи. Свойства внешне выглядят как поля и используются аналогично доступным полям (с некоторыми исключениями), однако фактически при обращении к ним происходит вызов методов доступа. Таким образом, свойства можно рассматривать как «умные» поля данных, сопровождающие доступ к внутренним данным объекта какими-либо дополнительными действиями (например, когда изменение координаты объекта сопровождается его перерисовкой на новом месте). Свойства, по сути — не более чем синтаксический
сахар, поскольку никаких новых возможностей они не добавляют, а лишь скрывают вызов методов доступа. Конкретная языковая реализация свойств может быть разной. Например, в C# объявление свойства непосредственно содержит код методов доступа, который вызывается только при работе со свойствами, то есть не требует отдельных методов доступа, доступных для непосредственного вызова. В Delphi объявление свойства содержит лишь имена методов доступа, которые должны вызываться при обращении к полю. Сами методы доступа представляют собой обычные методы с некоторыми дополнительными требованиями к сигнатуре.
Полиморфизм реализуется путём
введения в язык правил, согласно которым
переменной типа «класс» может быть присвоен
объект любого класса-потомка её класса.
Подходы
к проектированию программ в целом
ООП ориентировано на разработку крупных
программных комплексов, разрабатываемых
командой программистов (возможно, достаточно
большой). Проектирование системы в целом,
создание отдельных компонент и их объединение
в конечный продукт при этом часто выполняется
разными людьми, и нет ни одного специалиста,
который знал бы о проекте всё.
Объектно-ориентированное проектирование
состоит в описании структуры и поведения
проектируемой системы, то есть, фактически,
в ответе на два основных вопроса:
Из каких частей состоит система.
В чём состоит ответственность каждой
из частей.
Выделение частей производится таким
образом, чтобы каждая имела минимальный
по объёму и точно определённый набор
выполняемых функций (обязанностей), и
при этом взаимодействовала с другими
частями как можно меньше.
Дальнейшее уточнение приводит к выделению
более мелких фрагментов описания. По
мере детализации описания и определения
ответственности выявляются данные, которые
необходимо хранить, наличие близких по
поведению агентов, которые становятся
кандидатами на реализацию в виде классов
с общими предками. После выделения компонентов
и определения интерфейсов между ними
реализация каждого компонента может
проводиться практически независимо от
остальных (разумеется, при соблюдении
соответствующей технологической дисциплины).
Большое значение имеет правильное построение
иерархии классов. Одна из известных проблем
больших систем, построенных по ООП-технологии —
так называемая проблема хрупкости
базового класса. Она состоит в том, что на поздних этапах разработки, когда иерархия классов построена и на её основе разработано большое количество кода, оказывается трудно или даже невозможно внести какие-либо изменения в код базовых классов иерархии (от которых порождены все или многие работающие в системе классы). Даже если вносимые изменения не затронут интерфейс базового класса, изменение его поведения может непредсказуемым образом отразиться на классах-потомках. В случае крупной системы разработчик базового класса не просто не в состоянии предугадать последствия изменений, он даже не знает о том, как именно базовый класс используется и от каких особенностей его поведения зависит корректность работы классов-потомков.
Родственные
методологии
Компонентное программирование —
следующий этап развития ООП; прототип-
и класс-ориентированное программирование — разные подходы к созданию программы, которые могут комбинироваться, имеющие свои преимущества и недостатки.
Компонентное программирование
Компонентно-ориентированное
программирование — это своеобразная
«надстройка» над ООП, набор правил и ограничений,
направленных на построение крупных развивающихся
программных систем с большим временем
жизни. Программная система в этой методологии
представляет собой набор компонентов
с хорошо определёнными интерфейсами.
Изменения в существующую систему вносятся
путём создания новых компонентов в дополнение
или в качестве замены ранее существующих.
При создании новых компонентов на основе
ранее созданных запрещено использование
наследования реализации — новый компонент
может наследовать лишь интерфейсы базового.
Таким образом компонентное программирование
обходит проблему хрупкости базового
класса.
Прототипное программирование
Прототипное программирование, сохранив часть черт ООП, отказалось от базовых понятий — класса и наследования.
Вместо механизма
описания классов и порождения экземпляров
язык предоставляет механизм создания
объекта (путём задания набора полей и
методов, которые объект должен иметь)
и механизм клонирования объектов.
Каждый вновь созданный
объект является «экземпляром без класса».
Каждый объект может стать прототипом — быть использован
для создания нового объекта с помощью
операции клонирования. После клонирования новый объект может быть изменён, в частности, дополнен новыми полями и методами.
Клонированный объект
либо становится полной копией прототипа,
хранящей все значения его полей и дублирующей
его методы, либо сохраняет ссылку на прототип,
не включая в себя клонированных полей
и методов до тех пор, пока они не будут
изменены. В последнем случае среда исполнения
обеспечивает механизм делегирования — если при обращении
к объекту он сам не содержит нужного метода
или поля данных, вызов передаётся прототипу,
от него, при необходимости — дальше
по цепочке.
Производительность
объектных программ
Гради Буч указывает на следующие причины, приводящие к снижению производительности программ из-за использования объектно-ориентированных средств:
Динамическое связывание
методов.
Обеспечение полиморфного
поведения объектов приводит к необходимости
связывать методы, вызываемые программой
(то есть определять, какой конкретно метод
будет вызываться) не на этапе компиляции,
а в процессе исполнения программы, на
что тратится дополнительное время. При
этом реально динамическое связывание
требуется не более чем для 20 % вызовов,
но некоторые ООП-языки используют его постоянно.
Значительная глубина
абстракции.
ООП-разработка часто приводит к созданию «многослойных» приложений, где выполнение объектом требуемого действия сводится к множеству обращений к объектам более низкого уровня. В таком приложении происходит очень много вызовов методов и возвратов из методов, что, естественно, сказывается на производительности.
Наследование «размывает»
код.
Код, относящийся
к «оконечным» классам иерархии наследования
(которые обычно и используются программой
непосредственно) — находится не только
в самих этих классах, но и в их классах-предках.
Относящиеся к одному классу методы фактически
описываются в разных классах. Это приводит
к двум неприятным моментам:
Класс-ориентированное программирование
Снижается скорость трансляции, так как
компоновщику приходится подгружать описания
всех классов иерархии.
Снижается производительность
программы в системе со страничной памятью —
поскольку методы одного класса физически
находятся в разных местах кода, далеко
друг от друга, при работе фрагментов программы,
активно обращающихся к унаследованным
методам, система вынуждена производить
частые переключения страниц.
Инкапсуляция снижает скорость
доступа к данным.
Запрет на прямой доступ к полям
класса извне приводит к необходимости
создания и использования методов доступа.
И написание, и компиляция, и исполнение
методов доступа сопряжено с дополнительными
расходами.
Динамическое создание и уничтожение
объектов.
Динамически создаваемые объекты,
как правило, размещаются в куче, что менее
эффективно, чем размещение их на стеке
и, тем более, статическое выделение памяти
под них на этапе компиляции.
Несмотря на отмеченные недостатки,
Буч утверждает, что выгоды от использования
ООП более весомы. Кроме того, повышение
производительности за счёт лучшей организации ООП-кода, по его словам, в некоторых случаях компенсирует дополнительные накладные расходы на организацию функционирования программы. Можно также заметить, что многие эффекты снижения производительности могут сглаживаться или даже полностью устраняться за счёт качественной оптимизации кода компилятором. Например, упомянутое выше снижение скорости доступа к полям класса из-за использования методов доступа устраняется, если компилятор вместо вызова метода доступа использует инлайн-подстановку (современные компиляторы делают это вполне уверенно).
Критика ООП
Критикуется
явно высказываемое или подразумеваемое
в работах некоторых пропагандистов ООП,
а также в рекламных материалах «объектно-ориентированных»
средств разработки представление об
объектном программировании как о некоем
всемогущем подходе, который магическим
образом устраняет сложность программирования.
Как замечали многие, в том числе упомянутые
выше Брукс и Дейкстра, «серебряной пули не существует» — независимо от того, какой парадигмы программирования придерживается разработчик, создание нетривиальной сложной программной системы всегда сопряжено со значительными затратами интеллектуальных ресурсов и времени. Из наиболее квалифицированных специалистов в области ООП никто, как правило, не отрицает справедливость критики этого типа.
Оспаривание
эффективности разработки методами ООП.
Критики
оспаривают тезис о том, что разработка
объектно-ориентированных программ требует
меньше ресурсов или приводит к созданию
более качественного ПО. Проводится сравнение
затрат на разработку разными методами,
на основании которого делается вывод
об отсутствии у ООП преимуществ в данном
направлении. Учитывая крайнюю сложность
объективного сравнения различных разработок,
подобные сопоставления, как минимум,
спорны. С другой стороны получается что
ровно так же спорны и утверждения об эффективности
ООП.
Указывается
на то, что целый ряд «врождённых особенностей» ООП-технологии делает построенные на её основе программы технически менее эффективными, по сравнению с аналогичными необъектными программами. Не отрицая действительно имеющихся дополнительных накладных расходов на организацию работы ООП-программ (см. раздел «Производительность» выше), нужно, однако, отметить, что значение снижения производительности часто преувеличивается критиками. В современных условиях, когда технические возможности компьютеров чрезвычайно велики и постоянно растут, для большинства прикладных программ техническая эффективность оказывается менее существенна, чем функциональность, скорость разработки и сопровождаемость. Лишь для некоторого, очень ограниченного класса программ (ПО встроенных систем, драйверы устройств, низкоуровневая часть системного ПО, научное ПО) производительность остаётся критическим фактором.
Критика
отдельных технологических решений в ООП-языках и библиотеках.
Эта
критика многочисленна, но затрагивает
она не ООП как таковое, а приемлемость
и применимость в конкретных случаях тех
или иных реализаций её механизмов. Одним
из излюбленных объектов критики является
язык C++, входящий в число наиболее распространённых
промышленных ООП-языков.