Я очень новичок в программировании и немного смущен чтением \ слушанием различных соглашений из разных источников:
Есть ли у объектно-ориентированного программирования 4 или 5 концепций?
Как новичок, я понимаю, что это 5 концепций:
- абстракция
- наследование
- Инкапсуляция
- Полиморфизм
- модульность
Так почему же я не нашел более «строгого» определения, и, кажется, существует несколько вариантов этих понятий?
Ответы:
Причина, по которой вы находите различные объяснения того, что означает объектно-ориентированное программирование, заключается в том, что нет ни одного человека или организации, обладающих полномочиями формулировать строгое универсально применимое определение.
Объектно-ориентированное программирование не является стандартом ISO или научным законом. Это философия. Как и во всех других философских подходах, существуют всевозможные интерпретации, и ни одна интерпретация не является универсально применимой. Когда вы читаете текст, в котором говорится о том, какие концепции следует соблюдать при разработке архитектуры программного обеспечения, вы должны рассматривать это как руководство, основанное на мнениях, которые автор сформировал в ходе своего профессионального опыта, а не как универсальную правду.
источник
Как уже упоминали другие, «ОО» на самом деле не имеет никаких компонентов , потому что это способ думать о моделировании решений проблем, а не набор инструментов или набор четко определенных процессов.
Наследование и полиморфизм - это особенности языка программирования. Хорошо, что вы понимаете их, но помните, что они являются инструментами (что означает, что, как и с любыми другими инструментами, они должны использоваться только для решения конкретных проблем, а не рассматриваться как цель или что-то, к чему нужно стремиться). Вы можете (и часто должны) написать «ОО» код, не используя ни один из них. Некоторые из лучших «ОО» -кодов, которые я когда-либо видел, очень мало используют наследование или полиморфизм.
Абстракция, инкапсуляция и модульность связаны не столько с кодом, сколько с тем, как вы смотрите на проблему, как вы пытаетесь понять эту проблему, как вы разрабатываете и структурируете свое решение в коде.
Кроме того, эти дизайнерские идеи не являются исключительными для "ОО". Скорее всего, вы, вероятно, понимаете их сейчас на базовом уровне, который может включать в себя способность объяснить идеальное для учебника определение и применить их к несколько нетривиальным задачам; хотя более глубокому тесту понимания дается очень большая сложная проблема, и какую сложность вы можете решить.
Еще одним тестом понимания является подход, который вы используете для решения проблемы; и новички в «ОО», которых часто обучают ОО с точки зрения моделирования данных (потому что именно так большинство людей привыкли понимать это еще в 1990-х годах), и часто в конечном итоге фокусируются на неправильных аспектах проблемы - т.е. слишком много данных, и они не уделяют достаточного внимания поведению.
Например, классические примеры часто ссылаются на сущности , такие как
Dog
,Cat
,Elephant
,Seagull
,Shark
и т.д. Попавшие в «ОО» часто смотрят на такие примеры и сразу же думать : «О, мне нужен базовый объект под названиемAnimal
» , и они даже могут в конечном итоге с другими промежуточные объекты, такие какMammal
иAmphibian
в аккуратной иерархии наследования, с различными атрибутами в каждом.Хотя этот способ мышления демонстрирует очень базовое понимание нескольких концепций ОО, опытный ОО-программист никогда не подойдет к этому и не придет к такому выводу (и на самом деле будет жаловаться, что у них недостаточно информации), потому что этот подход демонстрирует сущность. моделирование, а не моделирование ОО, и потому, что надуманный пример ничего не говорит о поведении этих животных (и многие люди в наши дни утверждают, что суть ОО заключается в поведении и функциональности).
Путь к изучению «ОО» традиционно состоит в том, чтобы тратить время на построение неправильных абстракций, когда вы либо ничего не знаете (или слишком мало) о поведении моделируемой проблемы, либо когда вы совершаете ошибку, сосредотачивая свое внимание на объектах, а не на функциональность, хотя отчасти это связано с тем, что многие книги, курсы и онлайн-учебники, написанные за эти годы, долгое время (неправильно) наставляли учеников на этом пути (хотя ситуация меняется).
В целом, ваше понимание зависит от опыта. Те концепции, которые вы выучили до сих пор, являются хорошим началом, есть больше концепций, которые вам необходимо изучить в процессе (например, принципы «SOLID» и «DRY»), и вам придется потратить много времени на изучение теория на практике с действительно сложными проблемами до того, как все это «защелкнется».
источник
Термин «объектная ориентация» был придуман доктором Аланом Кей, поэтому он является авторитетным источником того, что он означает, и он определяет его таким образом :
Давайте разберемся с этим:
С точки зрения реализации обмен сообщениями - это вызов процедур с поздней привязкой, и если вызовы процедур связаны с поздней привязкой, вы не можете знать во время разработки, что вы собираетесь вызывать, поэтому вы не можете делать какие-либо предположения о конкретном представлении состояния. Итак, на самом деле речь идет об обмене сообщениями, позднее связывание является реализацией обмена сообщениями, а инкапсуляция является следствием этого.
Позже он пояснил, что « большая идея - это« обмен сообщениями » », и сожалеет, назвав его «объектно-ориентированным» вместо «ориентированного на сообщения», потому что термин «объектно-ориентированный» акцентирует внимание на неважной вещи (объектах). ) и отвлекает от того, что действительно важно (обмен сообщениями):
(Конечно, сегодня большинство людей даже не фокусируются на предметах, а на классах, что еще более неправильно).
Обмен сообщениями является фундаментальным для ОО, как метафора и как механизм.
Если вы отправляете кому-то сообщение, вы не знаете, что они с ним делают. Только вещь , которую вы можете наблюдать, их ответ. Вы не знаете, обрабатывали ли они сообщение сами (т. Е. Если у объекта есть метод), пересылали ли они сообщение кому-либо еще (делегирование / передача), даже если они его понимали. Вот что такое инкапсуляция, вот что такое OO. Вы даже не можете отличить прокси от реального, пока он отвечает так, как вы ожидаете.
Более «современным» термином для «обмена сообщениями» является «динамическая диспетчеризация метода» или «вызов виртуального метода», но он теряет метафору и фокусируется на механизме.
Итак, есть два способа взглянуть на определение Алана Кея: если вы посмотрите на него, стоящее само по себе, вы можете заметить, что обмен сообщениями - это в основном вызов процедуры с поздней привязкой, а поздняя привязка подразумевает инкапсуляцию, поэтому мы можем заключить, что # 1 и # 2 на самом деле являются избыточными, а OO - все о позднем связывании.
Однако позже он пояснил, что важной вещью является обмен сообщениями, и поэтому мы можем взглянуть на него под другим углом зрения: обмен сообщениями связан с запозданием. Теперь, если бы обмен сообщениями был единственно возможным, тогда №3 был бы тривиально верным: если есть только одна вещь, и эта вещь связана с опозданием, то все вещи связаны с опозданием. И снова, инкапсуляция следует из обмена сообщениями.
Подобные пункты также в On Понимание абстракции данных, Revisited по Уильям Р. Кук , а также его предложение по упрощению, современные определения «объекта» и «объектно - ориентированного» .
В Smalltalk-72 не было даже никаких объектов! Были только потоки сообщений, которые были проанализированы, переписаны и перенаправлены. Сначала появились методы (стандартные способы анализа и перенаправления потоков сообщений), затем появились объекты (группы методов, которые разделяют некоторые частные состояния). Наследование появилось намного позже, и классы были введены только как способ поддержки наследования. Если бы исследовательская группа Кея уже знала о прототипах, они, вероятно, никогда бы не представили классы.
Бенджамин Пирс в « Типах и языках программирования» утверждает, что определяющей чертой объектной ориентации является открытая рекурсия .
Итак, по словам Алана Кея, ОО - это все о сообщениях. По словам Уильяма Кука, ОО - это динамическая диспетчеризация методов (что на самом деле одно и то же). По словам Бенджамина Пирса, OO - это все об открытой рекурсии, что в основном означает, что самореференции динамически разрешаются (или, по крайней мере, так думают), или, другими словами, обмениваются сообщениями.
Как вы можете видеть, человек, который придумал термин «ОО», имеет довольно метафизический взгляд на объекты, Кук - довольно прагматичный взгляд, а Пирс - очень строгий математический взгляд. Но важно то, что философ, прагматик и теоретик все согласны! Обмен сообщениями является одним из столпов ОО. Период.
Обратите внимание, что здесь нет упоминания о наследовании! Наследование не обязательно для ОО. В целом, большинство ОО-языков имеют некоторый способ повторного использования реализации, но это не обязательно должно быть наследованием. Это также может быть, например, некоторая форма делегирования. Фактически, в Орландском договоре делегирование рассматривается как альтернатива наследования, а также то, как различные формы делегирования и наследования приводят к различным точкам проектирования в пространстве разработки объектно-ориентированных языков. (Обратите внимание, что на самом деле даже в языках, которые поддерживают наследование, таких как Java, людей фактически учат избегать его, снова указывая на то, что оно не является необходимым для ОО.)
источник
Как утверждает @Philipp, корень проблемы заключается в том, что нет официального определения того, что делает язык программирования объектно-ориентированным. Действительно, это, наверное, хорошая вещь. Существует множество способов поддержки ОО-программирования, каждый из которых имеет свои преимущества и недостатки. Дискуссия о том, какие языки более "чисты", на самом деле многого не дает.
Однако, глядя на 5 атрибутов, которые вы перечислили, на мой взгляд, модульность определенно является странной. Модульность действительно является атрибутом программы, а не языка программирования. На лингвистическом уровне атрибутом является «поддержка модульности», который обычно принимает форму механизма «модули» или «пакеты».
Но мое настоящее возражение против модульности заключается в том, что он не является ключевым для ОО-программирования или ОО-языков программирования, поскольку архетипический язык программирования Smalltalk-80 вообще не поддерживает модули. И когда вы думаете об этом, лингвистическая поддержка модулей во многих широко используемых OOPL является "слабой".
Модули предназначены для поддержки "программирования в целом" ... когда ваша кодовая база становится слишком большой для одного человека, чтобы ее можно было полностью понять. И вам не нужны модули на языке программирования для модуляции вашего кода.
Я не вступаю в дискуссию о другом 4 атрибуте и о том, являются ли (например) какие модели «наследования» чистыми ОО. Кроме того, хотя Алану Кей приписывают изобретение ОО-программирования, это не обязательно означает, что его определения ОО / и ООПЛ имеют первенство. Понятно, что это не так. Он авторитетный источник, но есть и другие источники , которые дают другие определения для ОО и OOPLs , что (на практике) нести больший вес.
источник