tl; dr: Вы можете иметь наследование без OO, вы можете иметь инкапсуляцию без OO, вы можете иметь полиморфизм без OO, вы даже можете иметь все три сразу без OO. С другой стороны, вы можете иметь ОО без наследования. Кроме того, существуют различные виды инкапсуляции (ADT-ориентированные и OO), поэтому не всякая инкапсуляция является OO.
Длинная версия:
Термин «объектно-ориентированное программирование» был придуман Аланом Кейем, поэтому он решает, что это значит. И он определяет это так :
Для меня ООП означает только обмен сообщениями, локальное хранение и защиту, а также скрытие процесса состояния и крайнюю позднюю привязку всех вещей.
С точки зрения реализации, обмен сообщениями - это вызов процедур с поздней привязкой, и если вызовы процедур с поздней привязкой, вы не можете знать во время разработки Что касается что вы собираетесь вызывать, поэтому вы не можете делать какие-либо предположения о конкретном представлении состояния. Итак, на самом деле речь идет об обмене сообщениями, позднее связывание является реализацией обмена сообщениями, а инкапсуляция является следствием этого.
Позже он пояснил, что « большая идея -« обмен сообщениями » », и сожалеет, назвав его «объектно-ориентированным» вместо «ориентированного на сообщения», потому что термин «объектно-ориентированный» акцентирует внимание на неважной вещи (объектах). ) и отвлекает от того, что действительно важно (обмен сообщениями):
Просто мягкое напоминание о том, что на последней OOPSLA я приложил некоторые усилия, чтобы напомнить всем, что Smalltalk - это не только НЕ синтаксис или библиотека классов, это даже не классы. Мне очень жаль, что я давно ввел термин «объекты» для этой темы, потому что он заставляет многих людей сосредоточиться на меньшей идее.
Основная идея - «обмен сообщениями» - это то, что является ядром Smalltalk / Squeak (и это то, что никогда не было полностью завершено в нашей фазе Xerox PARC). У японцев есть маленькое слово - ma - для «того, что находится между» - возможно, ближайший английский эквивалент - «interstitial». Ключом к созданию великолепных и расширяемых систем является гораздо больше, чем дизайн их модулей, а не их внутренние свойства и поведение. Подумайте об интернете - чтобы жить, он (а) должен позволять множество различных видов идей и реализаций, выходящих за рамки какого-либо единого стандарта, и (б) обеспечивать различные степени безопасной совместимости между этими идеями.
(Конечно, сегодня большинство людей даже не фокусируются на предметах, а на классах, что еще более неправильно).
Обмен сообщениями является основополагающим для ОО, как метафора и как механизм.
Если вы отправляете кому-то сообщение, вы не знаете, что они с ним делают. Только вещь , которую вы можете наблюдать, их ответ. Вы не знаете, обрабатывали ли они сообщение сами (т. Е. Если у объекта есть метод), пересылали ли они сообщение кому-либо еще (делегирование / передача), даже если они его понимали. Вот что такое инкапсуляция, вот что такое OO. Вы даже не можете отличить прокси от реального, пока он отвечает так, как вы ожидаете.
Более «современным» термином для «обмена сообщениями» является «динамическая диспетчеризация метода» или «вызов виртуального метода», но он теряет метафору и фокусируется на механизме.
Подобные пункты также в On Понимание абстракции данных, Revisited по Уильям Р. Кук , а также его предложение по упрощению, современные определения «объекта» и «объектно - ориентированного» .
Динамическая диспетчеризация операций является существенной характеристикой объектов. Это означает, что вызываемая операция является динамическим свойством самого объекта. Операции не могут быть идентифицированы статически, и в общем случае невозможно точно определить, какая операция будет выполнена в ответ на данный запрос, кроме как при ее запуске. Это точно так же, как с первоклассными функциями, которые всегда отправляются динамически.
В Smalltalk-72 не было даже никаких объектов! Были только потоки сообщений, которые были проанализированы, переписаны и перенаправлены. Сначала появились методы (стандартные способы анализа и перенаправления потоков сообщений), затем появились объекты (группы методов, которые разделяют некоторые частные состояния). Наследование появилось намного позже, и классы были введены только как способ поддержки наследования. Если бы исследовательская группа Кея уже знала о прототипах, они, вероятно, никогда бы не представили классы.
Каждый программист должен прочитать « Понимание абстракции данных» . Подробно объясняется, в чем именно разница между объектами и абстрактными типами данных. Он приводит примеры с использованием Java, и это чрезвычайно важно для этого вопроса, потому что и в примерах ADT, и в примерах Object он использует наследование, инкапсуляцию и полиморфизм, но только один из примеров является объектно-ориентированным! Другими словами: вы можете иметь наследование, инкапсуляцию и полиморфизм, вы даже можете иметь все три сразу и при этом не иметь ОО.
С другой стороны, вы можете иметь ОО без наследования. Как я намекал выше: оригинальные версии Smalltalk (язык, разработанный Аланом Кей, изобретателем термина «объектно-ориентированное программирование») не имели наследования.
Наконец, но не в последнюю очередь, в Орландском договоре обсуждается делегирование как альтернатива наследования и то, как различные формы делегирования и наследования приводят к различным точкам проектирования в пространстве разработки объектно-ориентированных языков. (Обратите внимание, что на самом деле даже в языках, которые поддерживают наследование, таких как Java, людей фактически учат избегать его, снова указывая на то, что оно не является необходимым для ОО.)