В первом семестре мы познакомились с такими понятиями ООП, как инкапсуляция, сокрытие данных, модульность, наследование и т. Д. Через Java и UML. (Java - мой первый язык программирования)
Ни одна из этих концепций ООП. Все они существуют вне ОО, независимо от ОО, и многие даже были изобретены до ОО.
Итак, если вы думаете , что что то , что OO это все о, то ваш вывод прав: вы можете сделать все из тех , на процедурных языках, потому что они не имеют ничего общего с ОО .
Например, одна из основополагающих статей о модульности - «Критерии для использования при разложении систем на модули» . Там нет упоминания о OO там. (Он был написан в 1972 году, к тому времени ОО все еще оставалась неясной нишей, хотя ему уже более десяти лет.)
Хотя абстракция данных важна в ОО, она является скорее следствием основной функции ОО (обмена сообщениями), чем определяющей. Кроме того, очень важно помнить, что существуют различные виды абстракции данных. Два наиболее распространенных вида абстракции данных, используемых сегодня (если мы игнорируем «никакой абстракции вообще», которая, вероятно, все еще используется больше, чем два других вместе взятых), это Абстрактные типы данных и объекты . Итак, просто говоря «сокрытие информации», «инкапсуляция» и «абстракция данных», вы ничего не сказали об ОО, поскольку ОО - это всего лишь одна из форм абстракции данных, и эти два на самом деле принципиально различны:
- В случае абстрактных типов данных механизмом абстракции является система типов ; это система типов, которая скрывает реализацию. (Система типов не обязательно должна быть статичной.) В объектах реализация скрыта за процедурным интерфейсом , который не требует типов. (Например, это можно реализовать с помощью замыканий, как это делается в ECMAScript.)
- В случае абстрактных типов данных экземпляры разных ADT инкапсулированы друг в друга, но экземпляры одного ADT могут проверять и получать доступ к представлению и частной реализации друг друга. Объекты всегда изолированы от всего . Только объект сам может проверить свое собственное представительство и доступ к собственным реализации. Никакой другой объект , даже другие объекты того же типа, другие экземпляры того же класса, другие объекты, имеющие тот же прототип, клоны объекта или что-либо еще, могут это сделать. Никто .
Кстати, это означает, что в Java классы не являются объектно-ориентированными. Два экземпляра одного класса могут получить доступ к представлению друг друга и частной реализации. Поэтому экземпляры классов не являются объектами, а фактически являются экземплярами ADT. Java interface
s, однако, действительно обеспечивают объектно-ориентированной абстракции данных. Итак, другими словами: только экземпляры интерфейсов являются объектами в Java, экземпляры классов - нет.
В основном, для типов вы можете использовать только интерфейсы. Это означает, что типы параметров методов и конструкторов, типы возвращаемых методов, типы полей экземпляров, статические поля и локальные поля, аргумент instanceof
оператора или оператора приведения и аргументы типа для конструктора универсального типа всегда должны быть интерфейсами. Класс может использоваться только сразу после new
оператора, нигде больше.
Например, для модульности мы можем просто разделить программу на множество небольших программ, которые выполняют четко определенные задачи, код которых содержится в отдельных файлах. Эти программы будут взаимодействовать друг с другом через их четко определенный ввод и вывод. Файлы могут быть защищены (зашифрованы?) Для достижения инкапсуляции. Для повторного использования кода мы можем просто вызывать эти файлы всякий раз, когда они нужны в новых программах. Разве это не отражает все, что такое ООП, или я упускаю что-то очень очевидное?
То, что вы описываете, является OO.
Это действительно хороший способ думать о ОО. Фактически, это именно то, что имели в виду первоначальные изобретатели ОО. (Алан Кей пошел еще дальше: он предполагал, что множество маленьких компьютеров посылают сообщения друг другу по сети.) То, что вы называете «программой», обычно называется «объектом», и вместо «звонка» мы обычно говорим «отправить сообщение». ».
Ориентация на объект - это все об обмене сообщениями (он же динамическая диспетчеризация ). Термин «Объектно-ориентированный» был придуман доктором Аланом Кей, главным разработчиком Smalltalk, и он определяет его так :
Для меня ООП означает только обмен сообщениями, локальное хранение и защиту, а также скрытие процесса состояния и крайнюю позднюю привязку всех вещей.
Давайте разберемся с этим:
- обмен сообщениями («отправка виртуального метода», если вы не знакомы с Smalltalk)
- государственный процесс должен быть
- локально сохраняется
- защищенный
- скрытый
- крайняя поздняя привязка всех вещей
С точки зрения реализации обмен сообщениями - это вызов процедур с поздней привязкой, и если вызовы процедур связаны с поздней привязкой, вы не можете знать во время разработки, что вы собираетесь вызывать, поэтому вы не можете делать какие-либо предположения о конкретном представлении состояния. Итак, на самом деле речь идет об обмене сообщениями, позднее связывание является реализацией обмена сообщениями, а инкапсуляция является следствием этого.
Позже он пояснил, что « большая идея - это« обмен сообщениями » », и сожалеет, назвав его «объектно-ориентированным» вместо «ориентированного на сообщения», потому что термин «объектно-ориентированный» акцентирует внимание на неважной вещи (объектах). ) и отвлекает от того, что действительно важно (обмен сообщениями):
Просто мягкое напоминание о том, что на последней OOPSLA я приложил некоторые усилия, чтобы напомнить всем, что Smalltalk - это не только НЕ синтаксис или библиотека классов, но даже не классы. Мне жаль, что я давно придумал термин «объекты» для этой темы, потому что он заставляет многих людей сосредоточиться на меньшей идее.
Основная идея - «обмен сообщениями» - вот что является ядром Smalltalk / Squeak (и это то, что никогда не было полностью завершено на нашей фазе Xerox PARC). У японцев есть маленькое слово - ma - для «того, что находится между» - возможно, ближайший английский эквивалент - «interstitial». Ключом к созданию великолепных и расширяемых систем является гораздо больше, чем дизайн их модулей, а не их внутренние свойства и поведение. Подумайте об Интернете - чтобы жить, он (а) должен позволять множество различных видов идей и реализаций, выходящих за рамки какого-либо единого стандарта, и (б) обеспечивать различные степени безопасного взаимодействия между этими идеями.
(Конечно, сегодня большинство людей даже не сосредотачиваются на предметах, а на классах, что еще более неправильно).
Обмен сообщениями является фундаментальным для ОО, как метафора и как механизм.
Если вы отправляете кому-то сообщение, вы не знаете, что они с ним делают. Только вещь , которую вы можете наблюдать, их ответ. Вы не знаете, обрабатывали ли они сообщение сами (т. Е. Если у объекта есть метод), пересылали ли они сообщение кому-либо еще (делегирование / передача), даже если они его понимали. Вот что такое инкапсуляция, вот что такое OO. Вы даже не можете отличить прокси-сервер от реального, если он отвечает так, как вы ожидаете.
Более «современным» термином для «обмена сообщениями» является «динамическая диспетчеризация метода» или «вызов виртуального метода», но он теряет метафору и фокусируется на механизме.
Итак, есть два способа взглянуть на определение Алана Кея: если вы посмотрите на него, стоящее само по себе, вы можете заметить, что обмен сообщениями - это в основном вызов процедуры с поздней привязкой, а поздняя привязка подразумевает инкапсуляцию, поэтому мы можем заключить, что # 1 и # 2 на самом деле являются избыточными, а OO - все о позднем связывании.
Однако позже он пояснил, что важной вещью является обмен сообщениями, и поэтому мы можем взглянуть на него под другим углом зрения: обмен сообщениями связан с запозданием. Теперь, если бы обмен сообщениями был единственно возможным, тогда №3 был бы тривиально верным: если есть только одна вещь, и эта вещь связана с опозданием, то все вещи связаны с опозданием. И снова, инкапсуляция следует из обмена сообщениями.
Подобные замечания также делаются в « Об понимании абстракции данных», вновь рассмотренном Уильямом Кук, а также в его предложении по упрощенным, современным определениям «Объект» и «Объектно-ориентированный» :
Динамическая диспетчеризация операций является существенной характеристикой объектов. Это означает, что вызываемая операция является динамическим свойством самого объекта. Операции не могут быть идентифицированы статически, и в общем случае невозможно точно знать, какая операция будет выполнена в ответ на данный запрос, кроме как при ее запуске. Это точно так же, как с первоклассными функциями, которые всегда отправляются динамически.
В Smalltalk-72 даже не было никаких объектов! Были только потоки сообщений, которые были проанализированы, переписаны и перенаправлены. Сначала появились методы (стандартные способы анализа и перенаправления потоков сообщений), затем появились объекты (группы методов, которые разделяют некоторые частные состояния). Наследование появилось намного позже, и классы были введены только как способ поддержки наследования. Если бы исследовательская группа Кея уже знала о прототипах, они, вероятно, никогда бы не представили классы.
Бенджамин Пирс в « Типах и языках программирования» утверждает, что определяющей чертой объектно-ориентации является открытая рекурсия .
Итак, по словам Алана Кея, OO - это все о сообщениях. По словам Уильяма Кука, ОО - это динамическая диспетчеризация методов (что на самом деле одно и то же). По словам Бенджамина Пирса, OO - это все об открытой рекурсии, что в основном означает, что самореференции динамически разрешаются (или, по крайней мере, так думают), или, другими словами, обмениваются сообщениями.
Как видите, человек, который придумал термин «ОО», имеет довольно метафизический взгляд на объекты, Кук - довольно прагматичный взгляд, а Пирс - очень строгий математический взгляд. Но важно то, что философ, прагматик и теоретик все согласны! Обмен сообщениями является одним из столпов ОО. Период.
Обратите внимание, что здесь нет упоминания о наследовании! Наследование не обязательно для ОО. В общем, большинство ОО-языков имеют некоторый способ повторного использования реализации, но это не обязательно должно быть наследованием. Это также может быть, например, некоторая форма делегирования. Фактически, в Орландском договоре делегирование рассматривается как альтернатива наследования, и как различные формы делегирования и наследования приводят к различным точкам проектирования в пространстве проектирования объектно-ориентированных языков. (Обратите внимание, что на самом деле даже в языках, которые поддерживают наследование, таких как Java, людей фактически учат избегать его, снова указывая на то, что оно не нужно для ОО.)