Объе́ктно-ориенти́рованное программи́рование (сокр. ООП) — методология или стиль программирования на основе описания типов/моделей предметной области и их взаимодействия, представленных порождением из прототипов или как экземпляры классов, которые образуют иерархию наследования.
Идеологически, ООП — подход к программированию как к моделированию информационных объектов, решающий на более высоком абстрактном уровне основную задачу структурного программирования — структурирование информации с точки зрения управляемости. Это позволяет управлять самим процессом моделирования и реализовывать крупные программные проекты.
Управляемость для иерархических систем предполагает минимизацию избыточности данных (аналогичную нормализации) и их целостность, поэтому созданное удобно управляемым — будет и удобно пониматься. Таким образом, через тактическую задачу управляемости решается стратегическая задача — транслировать понимание задачи программистом в наиболее удобную для дальнейшего использования форму.
Методология ООП развивает и расширяет принципы объектного программирования.
Основные принципы структурирования в случае ООП связаны с различными аспектами базового понимания предметной задачи, которое требуется для оптимального управления соответствующей моделью: абстрагирование выделяет существенные характеристики некоторого объекта, отличающие его от всех других видов объектов и, таким образом, четко определяет его концептуальные границы с точки зрения наблюдателя инкапсуляция — это процесс отделения друг от друга элементов объекта, определяющих его устройство и поведение; инкапсуляция служит для того, чтобы изолировать контрактные обязательства абстракции от их реализации иерархия в виде наследования (генерализации) — такого отношения между классами (отношение родитель/потомок), когда один класс заимствует, а также расширяет и/или специализирует (уточняет) структуру и функциональный контракт одного или нескольких родительских классов модульность — это свойство системы, которая была разложена на внутренне связные, но слабо связные между собой модули Без следования любому из этих принципов модель не будет объектно-ориентированной.
То есть фактически речь идёт о прогрессирующей организации информации согласно первичным семантическим критериям: «важное/неважное», «ключевое/подробности», «родительское/дочернее», «единое/множественное». Прогрессирование, в частности, на последнем этапе даёт возможность перехода на следующий уровень детализации, что замыкает общий процесс.
Дополнительные свойства системы.
типизация — это способ защититься от использования объектов одного класса вместо другого, или по крайней мере управлять таким использованием. виртуальный полиморфизм — при динамическом связывании указатель (или ссылка) могут ссылаться на объект любого типа совместимого по иерархии наследования с типом указателя или ссылки соответственно параллелизм — это свойство, отличающее активные объекты от пассивных; параллелизм в объектно-ориентированном программировании, как и другие принципы, возник не на пустом месте, а явился результатом привнесения объектной идеи в теорию параллельных вычислений сохраняемость — это способность объекта существовать во времени, переживая породивший его процесс, и (или) в пространстве, перемещаясь из своего первоначального адресного пространства
Обычный человеческий язык в целом отражает идеологию ООП, начиная с инкапсуляции представления о предмете в виде его имени и заканчивая полиморфизмом использования слова в переносном смысле, что в итоге развивает выражение представления через имя предмета до полноценного понятия-класса.
Основные понятия
Абстракция данных Абстрагирование означает выделение значимой информации и исключение из рассмотрения незначимой. В ООП рассматривают лишь абстракцию данных (нередко называя её просто «абстракцией»), подразумевая набор наиболее значимых характеристик объекта, доступных остальной программе. Инкапсуляция Инкапсуляция — свойство системы, позволяющее объединить данные и методы, работающие с ними, в классе. Одни языки (например, C++, Java или Ruby) отождествляют инкапсуляцию с сокрытием, но другие (Smalltalk, Eiffel, OCaml) различают эти понятия. Наследование Наследование — свойство системы, позволяющее описать новый класс на основе уже существующего с частично или полностью заимствованной функциональностью. Класс, от которого производится наследование, называется базовым, родительским или суперклассом. Новый класс — потомком, наследником, дочерним или производным классом. Полиморфизм подтипов Полиморфизм подтипов (в ООП называемый просто «полиморфизмом») — свойство системы, позволяющее использовать объекты с одинаковым интерфейсом без информации о типе и внутренней структуре объекта. Другой вид полиморфизма — параметрический — в ООП называют обобщённым программированием. Класс Класс — универсальный, комплексный тип данных, состоящий из тематически единого набора «полей» (переменных более элементарных типов) и «методов» (функций для работы с этими полями), то есть он является моделью информационной сущности с внутренним и внешним интерфейсами для оперирования своим содержимым (значениями полей). В частности, в классах широко используются специальные блоки из одного или чаще двух спаренных методов, отвечающих за элементарные операции с определённым полем (интерфейс присваивания и считывания значения, геттер-сеттер), которые имитируют непосредственный доступ к полю. Эти блоки называются «свойствами» и почти совпадают по конкретному имени со своим полем (например, имя поля может начинаться со строчной, а имя свойства — с заглавной буквы). Другим проявлением интерфейсной природы класса является то, что при копировании соответствующей переменной через присваивание копируется только интерфейс, но не сами данные, то есть класс — ссылочный тип данных. Переменная-объект, относящаяся к заданному классом типу, называется экземпляром этого класса. При этом в некоторых исполняющих системах класс также может представляться некоторым объектом при выполнении программы посредством динамической идентификации типа данных. Обычно классы разрабатывают таким образом, чтобы обеспечить отвечающие природе объекта и решаемой задаче целостность данных объекта, а также удобный и простой интерфейс. В свою очередь, целостность предметной области объектов и их интерфейсов, а также удобство их проектирования, обеспечивается наследованием. Объект Сущность в адресном пространстве вычислительной системы, появляющаяся при создании экземпляра класса (например, после запуска результатов компиляции и связывания исходного кода на выполнение).
Классификация подвидов ООП и Мартин Абади построили теоретическое обоснование ООП и классификацию на основе этого обоснования. Они отмечают, что выделенные ими понятия и категории вместе встречаются далеко не во всех ОО-языках, большинство языков поддерживают лишь подмножества теории, а порой и своеобразные отклонения от неё.
Ключевые понятия: квантификация переменных типа (универсальная, экзистенциальная, ); ( — отношения «супертип-подтип»); включение ( — см. принцип подстановки Барбары Лисков) — частный случай подтипизации — см. подтипизация на записях; объект; объектный тип (фактически, специальная форма «записи», в число полей которой входят функции первого класса); класс.
Класс описывает абстрактное поведение. Объектные типы строятся на основе класса посредством добавления различных приватных полей и методов. Объект (то есть значение объектного типа, традиционно называемое «экземпляром класса») порождается конструктором на основе начальных параметров.
Традиционно перечисляемые основные принципы ООП не апеллируют к данному теоретическому обоснованию, а являются устоявшимися в сообществе догмами (что приводит к сильному разбросу вариантов изложения в разных источниках). По большей части они относятся к языкам — потомкам Алгола и Симулы; в меньшей степени — к потомкам Smalltalk (в частности, часто упоминаемый принцип сокрытия в потомках Smalltalk семантически недоступен и идеологически считается несущественным). В значительно большей степени теоретически обоснованные концепции ООП поддерживают ОО-языки, развившиеся на поприще функционального программирования: OCaml, диалекты Haskell (O’Haskell, Mondrian), successor ML. Более того, основные идеи объектного моделирования в этом случае не требуют прямой поддержки со стороны языка, а могут быть сравнительно легко эмулированы.
Наиболее заметные отличия в проявлении показателей качества между языками разных видов:
В мейнстримных языках декларируемые принципы нацелены на повышение изначально низкого для императивного программирования коэффициента повторного использования кода. В полиморфно типизированных применение концепций ООП, напротив, означает очевидное его снижение из-за перехода от параметрического полиморфизма к ad-hoc-полиморфизму. В динамически типизированных языках (Smalltalk, Python, Ruby) эти принципы используются для логической организации программы, и их влияние на коэффициент повторного использования трудно спрогнозировать — он сильно зависит от дисциплины программиста. Например, в CLOS мультиметоды одновременно являются функциями первого класса, что позволяет рассматривать их одновременно и как , и как обобщённые (истинно полиморфные). Традиционные ОО-языки используют , то есть допустимость соиспользования объектов разных классов только при условии явного указания родственных отношений между классами. Для полиморфно типизированных языков характерна , то есть согласование классов между собой тем же механизмом, что и согласование числа 5 с типом int. Динамически типизированные языки также занимают здесь промежуточную позицию.
Обобщённое обоснование (включая множественную) в середине 1990-х годов построил Джузеппе Кастанья.
История
Объе́ктно-ориенти́рованное программирование возникло в результате развития идеологии процедурного программирования, где данные и подпрограммы (процедуры, функции) их обработки формально не связаны. Для дальнейшего развития объектно-ориентированного программирования часто большое значение имеют понятия события (так называемое событийно-ориентированное программирование) и компонента (компонентное программирование, КОП).
Взаимодействие объектов происходит посредством сообщений. Результатом дальнейшего развития ООП, по-видимому, будет агентно-ориентированое программирование, где агенты — независимые части кода на уровне выполнения. Взаимодействие агентов происходит посредством изменения среды, в которой они находятся.
Языковые конструкции, конструктивно не относящиеся непосредственно к объектам, но сопутствующие им для их безопасной (исключительные ситуации, проверки) и эффективной работы, инкапсулируются от них в аспекты (в аспектно-ориентированном программировании). Субъектно-ориентированное программирование расширяет понятие объекта посредством обеспечения более унифицированного и независимого взаимодействия объектов. Может являться переходной стадией между ООП и агентным программированием в части самостоятельного их взаимодействия.
Первым языком программирования, в котором были предложены основные понятия, впоследствии сложившиеся в парадигму, была Симула, но термин «объектная ориентированность» не использовался в контексте использования этого языка. В момент его появления в 1967 году в нём были предложены революционные идеи: объекты, классы, виртуальные методы и др., однако это всё не было воспринято современниками как нечто грандиозное. Фактически, Симула была «Алголом с классами», упрощающим выражение в процедурном программировании многих сложных концепций. Понятие класса в Симуле может быть полностью определено через композицию конструкций Алгола (то есть класс в Симуле — это нечто сложное, описываемое посредством примитивов).