Почему наследование, инкапсуляция и полиморфизм не являются столпами ООП? [закрыто]


16

Однажды я зашел в чат Stack Overflow и увидел фразу, в которой говорилось, что наследование, инкапсуляция и полиморфизм являются столпами ООП (в том смысле, что они являются фундаментальными, строительными подошвами).

Кроме того, есть аналогичный вопрос, который мне очень часто задавали на экзаменах в колледже и на собеседованиях, и правильным ответом всегда было утверждение, произнесенное в заголовке вопроса («Да, наследование, инкапсуляция и полиморфизм - это столпы ООП». ).

Но в чате Stack Overflow меня жестоко высмеивали, участники категорически не соглашались с таким утверждением. Итак, что не так с этим утверждением?

Кажется ли, что программисты обучаются разным вещам в постсоветских и американских колледжах?

Разве наследование, инкапсуляция и полиморфизм не считаются столпами ООП программистами из США / Великобритании?


7
Ваш вопрос не имеет контекста; мы не знаем, о чем думали люди в SO чате или на что они отвечали. Может быть, вы можете дать ссылку на разговор в чате, чтобы мы могли посмотреть на него? Тем не менее, я думаю, что это лучше всего решить в чате, а не здесь.
Роберт Харви

1
@ Роберт, слишком много времени прошло. Сомневаюсь, что вообще смогу найти ссылку на разговор. Но я согласен, что контекст важен. Я не виню кого-то или представляю себя невинной жертвой чата, я просто хочу знать правду.
PaulD

5
Гостиная. Вы сначала надели свой огнестойкий костюм?
Роберт Харви

1
Единственное значение, которое я могу дать этому предложению, это либо «вы можете иметь ООП без любого из них» (правда, но не имеет смысла, по крайней мере, для инкапсуляции), либо «вы также можете использовать их вне ООП», или что-то в этом роде.
SJuan76

2
Имо ОО имеет только одну опору, и это: «Государство». Как только ваш мозг мыслит в состоянии, вы получаете OO.
Питер Б

Ответы:


40

Разве наследование, инкапсуляция и полиморфизм не считаются столпами ООП программистами из США / Великобритании?

Многие программисты считают их столпами, и многие колледжи преподают ОО таким образом.

К сожалению, это также близорукий взгляд.

  • Наследование - это всего лишь один механизм, используемый для реализации ООП, и им можно злоупотреблять, чтобы не выполнять ООП.
  • Инкапсуляция - это концепция, полезная для программирования всех видов, ООП и нет.
  • Полиморфизм - это ... черта (?) Для описания поведения вычислений. Существует много способов достижения полиморфизма, не все из которых являются специфическими для ОО.

ООП имеет очень мало оснований, поскольку в действительности это очень концептуально: «Подход к дизайну вашей программы, думая о вещах как об объектах - связных пакетах данных и функциональности».

И в то время как современный дизайн программы плохо понимает, что нужно делать что-то «чисто ОО», большинство опытных программистов согласятся с тем, что принципы SOLID (или некоторое подмножество) являются более подходящими кандидатами для «столпов объектно-ориентированного программирования» (даже если они хорошо применять для не-ООП). Они не работают с этими условиями вообще. Вместо этого они используют понятия программных сущностей (из которых объекты являются одним), интерфейсов (из которых C # / Java / и т. Д. interface), Абстракции и подтипирования (из которых наследование является одной из форм).


10
Достойный ответ на принципиально неопровержимый вопрос.
Роберт Харви

3
ООП существует?
Тулаинс Кордова

5
Я бы сказал, что только инкапсуляция является «опорой» ООП. Самая большая разница между ООП и структурным программированием заключается в том, что объекты содержат код и данные, а не только данные (например, классическая структура Си). Две другие концепции в основном используются в ОО-языках, но не ограничиваются ОО и не требуются им.

3
Инкапсуляция @Snowman также не ограничивается ООП. Люди постоянно реализуют абстрактные типы данных на С и функциональных языках.
Доваль

2
И у @ JörgWMittag был хороший ответ относительно обмена сообщениями. Идея обмена сообщениями обязательно требует инкапсуляции. Сообщения обычно передаются в функцию или метод объекта, который затем воздействует на состояние, которое инкапсулировано в нем. Это не означает, что не-ОО-языки не могут также иметь передачу сообщений или инкапсуляцию, а лишь то, что это основополагающие идеи ООП.

23

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, людей фактически учат избегать его, снова указывая на то, что оно не является необходимым для ОО.)


Вы можете иметь "наследование", "полиморфизм" и "наследование" ... возможно, где-то там есть опечатка :)
slebetman

1
Этот ответ заставляет меня желать, чтобы мы могли «любимые» ответы тоже.
Чан-Хо Су

Определение Алана Кея устарело. ОО требует наследования, и если вы можете выполнять связывание как во время выполнения, так и во время компиляции, как в C ++, вы получаете производительность наравне с C.
Эрик Алапяя

Нет, его определение правильное. Вам вообще не нужно наследование, чтобы быть ОО. Языки-прототипы не используют наследование, как C ++, и они по-прежнему OO. Наследование используется только для реализации повторного использования кода, это даже не лучший способ, например, есть много лучших языков, которые имеют миксины. Это также не имеет ничего общего с привязкой, так как вы можете иметь динамическую диспетчеризацию, даже в C ++, когда вы можете использовать виртуальные методы. Производительность не имеет ничего общего с этим, это концепции высокого уровня, они не имеют производительности. Фактически, вы могли бы реализовать передачу сообщений в C и быть OO
Luiz Felipe
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.