Файл: Основные понятия объектно- ориентированного программирования.pdf

ВУЗ: Не указан

Категория: Курсовая работа

Дисциплина: Не указана

Добавлен: 04.04.2023

Просмотров: 160

Скачиваний: 2

ВНИМАНИЕ! Если данный файл нарушает Ваши авторские права, то обязательно сообщите нам.

Объектно-ориентированные концепции не зависят от используемого языка или инструмента, их скорее можно назвать способом мышления, взглядом на мир под определенным углом.[17] Главная идея заключается в том, что все программные разработки должны быть основаны на повторно используемых компонентах, как это происходит в других отраслях, например, в электронике или строительстве, а сам объектно-ориентированный подход диктует, какую форму эти компоненты должны принимать.[18]

Самый рациональный способ управления сложными системами был известен с древнейших времен — divide et impera (разделяй и властвуй). Выход — в декомпозиции системы на все меньшие и меньшие части, каждую из которых можно обрабатывать независимо от других. Решая любую сложносоставную задачу, мы должны проанализировать существующую проблему, выделить основные сущности и объединить эти сущности во множества, каждое из которых будет представлено своим состоянием и поведением. После этого можно представить каждое множество сущностей в виде класса, объявив в нём общие данные и функции, и обеспечить статическую взаимосвязь этих классов. В результате из реальных объектов предметной области мы получим организованную совокупность взаимодействующих программных объектов. Каждый из них является экземпляром определенного класса, классы же в свою очередь образуют иерархию на принципах наследования.[19] Можно сказать, что объектно-ориентированное программирование сводится к моделированию объектов, которые взаимодействуют друг с другом, посылая сообщения, в ответ на которые выполняют действия, описанные в методах, соответствующих сообщениям. Поскольку все возможные действия объекта описаны его методами, этот несложный механизм поддерживает все возможные варианты взаимодействий.[20]

Таким образом, основная мыслительная деятельность программиста реализуется главным образом в процессе описания класса. Именно на этом этапе продумываются и вводятся в структуру класса поля, методы и свойства. Чтобы понять ООП, нужно прежде всего развить в себе способность оперировать абстракциями и представлять задачу как набор взаимодействующих объектов. ООП — это не новый стиль программирования или новая группа языков, это всего лишь новая парадигма, которая требует перестройки сознания и навыков, пересмотра привычных подходов.[21]


Объектно-ориентированное программирование в основном нацелено на разработку крупных программных проектов. При этом создание отдельных элементов системы может выполняться разными специалистами. В отличие от функционального программирования ООП ставит в приоритет описание структуры проектируемой системы, а не её поведения. Цель в том, чтобы каждая элементарная единица проекта имела точно определённый набор функций и минимально вступала во взаимодействие с другими частями системы. Огромное значение при разработке программ имеет грамотное построение иерархии классов. Именно поэтому один из главных недостатков ООП — это проблема хрупкости базового класса. При полностью выстроенной иерархии оказывается очень трудным внести изменения в код классов-родителей, ведь даже малейшая доработка сразу отразится на классах-потомках.[22]

Среди основных ООП-методологий можно выделить:

Компонентное программирование — это своеобразный набор правил для построения больших программных систем с долгим временем жизни. Сама система представлена в виде набора компонентов с хорошо прописанными интерфейсами, а изменения вносятся за счет создания новых компонентов или замены старых. Причем при создании компонентов на основе ранее существующих использование наследования реализации находится под запретом — так обходится проблема хрупкости базового класса.[23]

В прототипном программировании отсутствуют классы и наследование. Новые объекты создаются по образу и подобию некоего объекта-прототипа, копии могут сохранять связь с объектом-родителем, наследуя изменения в прототипе. Каждый объект — это экземпляр без класса, который можно использовать для создания нового объекта путем клонирования.[24]

Класс-ориентированное программирование — это программирование, сфокусированное на данных, тесно связанных с поведением. Вместе они составляют класс, а все объекты разделены на классы и экземпляры. Класс определяет поведение для всех своих экземпляров, экземпляр является носителем данных. Новый экземпляр создаётся с помощью конструктора и имеет структуру и поведение, четко определенные классом, к которому он принадлежит.

2. Основные понятия ООП


2.1 Абстрагирование

Строго говоря, абстрагирование не является исключительным признаком ООП, да и программирования в целом. Создание разных уровней абстракции возможно практически во всех сферах познания человека. Например, мы можем говорить о материалах, не вникая в подробности их молекулярного строения, или рассуждать о предметах, не упоминая того, из каких материалов они произведены.[25]

В программировании абстракции существовали всегда. Начиная с первого программиста Ады Лавлейс и до наших времен люди создают в своих программах абстракции разной степени сложности, часто используя для этого простейшие средства. Например, Харольд Абельсон и Джеральд Джей Сассман в своей фундаментальной книге «Структура и интерпретация компьютерных программ» описывают разработку системы решения уравнений с поддержкой комплексных чисел, имея в наличии лишь процедуры и связные списки.

В объектно-ориентированном программировании под абстракцией понимается использование исключительно тех параметров и характеристик объекта, которые необходимы для его точного представления в системе. Абстрагирование является одним из важнейших инструментов ООП наряду с полиморфизмом, наследованием и инкапсуляцией. Цель в том, чтобы сократить представление об объекте до минимального, но достаточного для работы с ним и решения поставленной задачи.[26] Главная миссия разработчика — выделить наиболее значимые характеристики отдельного объекта, отличающие его от других, и определить его особенности для последующего рассмотрения и анализа.[27]

2.2 Инкапсуляция

Нередко инкапсуляцию рассматривают как признак, присущий только объектно-ориентированному программированию, но на самом деле она часто встречается и в других методиках. В ООП инкапсуляция неразрывно связана с абстрагированием. В частности, в сообществе С++ или Java принято рассматривать инкапсуляцию без сокрытия как неполноценную. В различных языках программирования понятие «инкапсуляция» может иметь одно или несколько определений:

  • механизм, ограничивающий доступ одних программных компонентов к другим;
  • конструкция, связывающая данные и методы, предназначенные для обработки этих данных.[28]

Суть инкапсуляции - в объединении в одно целое, как бы в «капсуле», всей информации об объекте - данных и методов их обработки. Таким образом, все объекты могут быть рассмотрены как минимальные самодостаточные единицы инкапсуляции.[29] Объекту нет необходимости показывать всю свою структуру и данные — на поверхности лежат лишь интерфейсы, необходимые для взаимодействия с другими сущностями, а детали реализации, не относящиеся к использованию объекта могут быть скрыты.[30] Сокрытие данных внутри объекта может осуществляться разными способами. Один из них — связывание данных с объектом путем присвоения им доступа private, public или protected. Данные с ключевым словом private могут быть использованы только внутри объекта, данными же с ключевым словом public можно оперировать и вне его. Точно так же, к функциям объекта с доступом private можно обращаться только из функций этого объекта, а к функциям объекта с доступом public предусмотрен доступ извне. Грамотное построение программы требует присваивать как можно большему количеству данных и функций статус private, обеспечивая обращение к объекту только через интерфейс. Одним из негласных правил является принцип сокрытия в объектах всего, что возможно, тем самым исключая непреднамеренный доступ и нежелательные изменения данных извне, что обеспечивает большую устойчивость и надежность объектов и всей системы в целом. Такую программу гораздо легче модифицировать, ведь при сохранении интерфейса класса можно менять его реализацию, не затрагивая внешний код. Понятие инкапсуляции тесно связано не только с сокрытием информации, но и с разграничением ответственности между клиентом и сервером. Клиенту необязательно знать, как реализованы те или иные методы в сервере. Ему достаточно знать, что данный метод делает и как к нему обратиться.[31]


В С++ определение класса состоит из двух частей: интерфейс и реализация. Интерфейс или протокол класса содержит объявление переменных и методов, а также комментарии, описывающие операции класса. Определения методов в том виде, в котором они реализованы в языке, отделены от интерфейса и размещаются в реализации класса. Интерфейс описан в заголовочном файле с расширением .H, а реализация — в файле с уточнением .CPP. В заголовочном файле размещаются объявления переменных класса и заголовки функций, реализующих методы.[32]

2.3 Наследование

Для похожих объектов в ООП предусмотрено совместное использование общих для них поведения и свойств. Самые распространенные способы организации такого использования — это классы и их наследование. Объекты, обладающие одинаковым поведением, объединяются в класс, который «хранит» информацию о структуре объектов и методах их взаимодействия. Наследование же дает возможность разделять поведение и структуру между несколькими классами.[33] Его можно назвать одним из самых мощных средств в любой объектно-ориентированной системе, ведь именно оно позволяет повторно использовать один и тот же код, избегая дублирования.[34]

Суть механизма наследования в следующем: некоторый класс объявляется базовым, из него порождается новый производный класс. Порожденный класс, обладающий состоянием и поведением базового, дополняется новыми, определёнными только в нём, данными и функциями. Каждый производный класс может добавить в структуру и поведение что-то свое, что-то из наследуемого может использовать без изменений, а что-то модифицировать. Таким образом, с помощью подклассов класс как бы «уточняет» поведение экземпляров, благодаря чему создаваемые объекты становятся более уникальными и специализированными. Классы могут наследовать друг у друга без каких-либо ограничений, тогда наследуемые компоненты будут автоматически накапливаться сверху вниз через все уровни, образуя древовидную структуру, так называемую иерархию классов. Чаще всего иерархия представляется в виде графа или дерева. Также стоит сказать, что наследование транзитивно, то есть класс может наследовать черты классов, находящихся от него на несколько уровней выше, при этом обладая способностью переопределять некоторые свойства и поведение.[35]


Язык C++/CLI, позволяет множественное наследование, при котором класс может быть создан на основе нескольких базовых классов. Однако это может привести к проблемам, связанным с неоднозначностью наследования. Чтобы избежать этого языки C# и Java, а также язык C++/CLI, запрещают множественное наследование классов, но допускают множественное наследование интерфейсов.[36]

Таким образом существует два основных типа наследования: при «простом» в системе фигурируют «базовые» («родительские») классы, производящие наследование и классы-«потомки» («наследники», «производные»), наследуемые от родительских.

В случае «множественного» наследования класс может иметь несколько предков, наследуя методы от каждого из них. Данный подход, являющийся более гибким, представлен в таких языках как «C++», «Python», «Eiffel», «UML». В то же время такое наследование может породить большое количество ошибок при наличии идентичных имён методов в классах-предках. Разработчики «Eiffel» попытались решить данную проблему следующим образом: при создании нового класса нужно указать не только импортируемые члены каждого из наследуемых классов, но и их именование в дочернем. Большинство современных объектно-ориентированных языков («C#», «Java», «Delphi») поддерживают возможность одновременного наследования от класса-предка и реализации методов нескольких интерфейсов одним и тем же классом, что позволяет заменить множественное наследование.[37]

2.4 Полиморфизм

Третья важнейшая сущность объектно-ориентированного программирования — это полиморфизм. Само слово, дословно означающее множественность форм (poly — много, morphos— форма, греч.), имеет похожие по значению термины во многих отраслях науки — полиморфные виды в биологии, полиморфные химические соединения. В программировании полиморфизм можно определить как возможность работы с разными типами данных, используя при этом единообразный интерфейс. Полиморфный объект — это некая сущность (переменная, аргумент функции), хранящая во время выполнения программы значения различных типов, полиморфные функции— это функции, имеющие полиморфные аргументы.[38] Как мы знаем, каждый подкласс наследует свойства и методы от родительских классов, однако ему могут потребоваться разные методы для ответа на одно и то же сообщение: здесь на помощь и приходит полиморфизм.[39] Его суть в возможности единообразного обращения к объектам при сохранении их уникального поведения. Одно и то же действие обозначается идентичным именем, которое используется во всей иерархии порождения классов. Например, базовый и производный классы могут иметь одноимённые функции, реализованные по-разному, обращаться к этим функциям тоже надо соответствующим образом. Полиморфизм дает возможность создавать множественные определения для операций и функций, а какое определение будет использоваться, зависит от контекста программы.[40]