Что делает язык объектно-ориентированным?

Поскольку спорить без содержательных терминов бессмысленно, я решил указать на слона в комнате и спросить: что именно делает язык "объектно-ориентированным"? Здесь я не ищу ответ из учебника, а на основе вашего опыта работы с ОО-языками, которые хорошо работают в вашей области, какой бы она ни была.

Смежный вопрос, который может помочь ответить первым: что такое архетип объектно-ориентированных языков и почему?

16 ответов

Решение

Определения для объектно-ориентации - это, конечно, огромное количество червей, но вот мои 2 цента:

Для меня Object-Orientation - это все, что связано с объектами, которые отправляют сообщения. Для меня это самая важная черта объектно-ориентированного языка.

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

  1. Объекты, отправляющие сообщения другим объектам
  2. Все является объектом
  3. Позднее связывание
  4. Подтип Полиморфизм
  5. Наследование или что-то такое же выразительное, как делегирование
  6. Инкапсуляция
  7. Сокрытие информации
  8. абстракция

Очевидно, что этот список очень спорный, поскольку он исключает большое разнообразие языков, которые широко рассматриваются как объектно-ориентированные, такие как Java, C# и C++, все из которых нарушают пункты 1, 2 и 3. Однако нет никаких сомнений что эти языки допускают объектно-ориентированное программирование (но также и C) и даже способствуют этому (чего нет в C). Итак, я стал называть языки, которые удовлетворяют этим требованиям, "чисто объектно-ориентированными".

В качестве архетипичных объектно-ориентированных языков я бы назвал Self и Newspeak.

Оба удовлетворяют вышеупомянутым требованиям. И те, и другие вдохновлены Smalltalk и являются его преемниками, и оба в некотором смысле действительно могут быть "более оригинальными". Что мне нравится в Self и Newspeak, так это то, что обе они доводят парадигму отправки сообщений до крайности (Newspeak даже больше, чем Self).

В Newspeak все это сообщение отправлено. Здесь нет переменных экземпляра, полей, атрибутов, констант, имен классов. Все они эмулируются с использованием геттеров и сеттеров.

В Self нет классов, только объекты. Это подчеркивает, о чем на самом деле ОО: объекты, а не классы.

В основном объектно-ориентированный действительно сводится к "передаче сообщений"

На процедурном языке я вызываю такую ​​функцию:

  f(x)

И имя f, вероятно, связано с конкретным блоком кода во время компиляции. (Если это не процедурный язык с функциями более высокого порядка или указателями на функции, но давайте на секунду проигнорируем эту возможность.) Таким образом, эта строка кода может означать только одну недвусмысленную вещь.

На объектно-ориентированном языке я передаю сообщение объекту, возможно, так:

 o.m(x) 

В этом случае. m - это не имя блока кода, а "селектор метода", и то, какой блок кода вызывается, в некоторой степени зависит от объекта o. Эта строка кода является более двусмысленной или общей, потому что она может означать разные вещи в разных ситуациях, в зависимости от o.

В большинстве языков ОО объект o имеет "класс", и класс определяет, какой блок кода вызывается. В паре ОО-языков (наиболее известный как Javascript) o не имеет класса, но имеет методы, непосредственно связанные с ним во время выполнения, или унаследовал их от прототипа.

Я отмечаю, что ни классы, ни наследование не нужны для того, чтобы язык был ОО. Но эта полиморфная обработка сообщений очень важна.

Хотя вы можете подделать это с помощью указателей функций, скажем, C, этого недостаточно для того, чтобы C был назван языком OO, потому что вам придется реализовать собственную инфраструктуру. Вы можете сделать это, и стиль ОО возможен, но язык не дал вам этого.

По словам Буча, следующие элементы: Major:

  • абстракция
  • Инкапсуляция
  • модульность
  • Иерархия (Наследование)

Незначительный:

  • Typing
  • совпадение
  • Упорство

На самом деле это не языки ОО, это код.

Можно написать объектно-ориентированный C-код (со структурами и даже членами-указателями функций, если хотите), и я видел несколько довольно хороших примеров этого. (Вспоминается Quake 2/3 SDK.) Также возможно написать процедурный (т.е. не OO) код на C++.

Учитывая это, я бы сказал, что поддержка языка для написания хорошего ОО-кода делает его "объектно-ориентированным языком". Я бы никогда не стал использовать члены-указатели на функции в структурах в C, например, для обычных функций-членов; поэтому я скажу, что C не является языком OO.

(Более подробно об этом можно сказать, что Python также не является объектно-ориентированным, с обязательной ссылкой "self" на каждом шаге и конструкторами, называемыми init, что-то еще; но это религиозное обсуждение.)

Smalltalk обычно считается архетипическим языком OO, хотя Simula часто упоминается как первый язык OO.

Текущие ОО-языки можно свободно классифицировать по тому, из какого языка они заимствуют большинство понятий:

  • Smalltalk-like: Ruby, Objective-C
  • Подобный Simula: C++, Object Pascal, Java, C#

Я рад поделиться с вами, ребята, это было довольно интересно и полезно для меня. Это отрывок из интервью Rolling Stone 1994 года, в котором Стив (не программист) объясняет ООП в простых терминах.

Джефф Гуделл: Не могли бы вы объяснить, простыми словами, что такое объектно-ориентированное программное обеспечение?

Стив Джобс: объекты похожи на людей. Они живут, дышат вещами, в которых есть знания о том, как делать вещи, и в них есть память, чтобы они могли помнить вещи. И вместо того, чтобы взаимодействовать с ними на очень низком уровне, вы взаимодействуете с ними на очень высоком уровне абстракции, как мы делаем прямо здесь.

Вот пример: если я ваш объект стирки, вы можете дать мне свою грязную одежду и отправить мне сообщение, которое гласит: "Можете ли вы выстирать мою одежду, пожалуйста". Я случайно знаю, где находится лучшее место для стирки в Сан-Франциско. является. И я говорю по-английски, и у меня в карманах есть доллары. Поэтому я выхожу, приветствую такси и говорю водителю отвезти меня в это место в Сан-Франциско. Я иду, стираю твою одежду, прыгаю обратно в такси, я возвращаюсь сюда. Я даю вам вашу чистую одежду и говорю: "Вот ваша чистая одежда".

Вы понятия не имеете, как я это сделал. Вы не знаете места прачечной. Может быть, вы говорите по-французски, и вы даже не можете поймать такси. Вы не можете заплатить за один, у вас нет долларов в кармане. Тем не менее, я знал, как все это сделать. И вам не нужно было ничего знать об этом. Вся эта сложность была скрыта во мне, и мы смогли взаимодействовать на очень высоком уровне абстракции. Вот что такое объекты. Они инкапсулируют сложность, и интерфейсы к этой сложности находятся на высоком уровне.

Насколько я могу судить, основной взгляд на то, что делает язык "объектно-ориентированным", поддерживает идею группировки данных и методов, которые работают с этими данными, что обычно достигается с помощью классов, модулей, наследования, полиморфизма и т. Д.

Посмотрите эту дискуссию, чтобы получить представление о том, что люди думают (думают?) Об объектно-ориентации.

Что касается "архетипического" языка ОО - это действительно Smalltalk, как указала Кристофер.

Simples:(сравните страховой характер)

1-Полиморфизм 2-Наследование 3-Инкапсуляция 4-Повторное использование.:)

По моему опыту, языки не объектно-ориентированные, а код.

Несколько лет назад я писал набор программ на AppleScript, который на самом деле не применял никаких объектно-ориентированных функций, когда я начал работать с OO. Неловко писать объекты в AppleScript, хотя можно создавать классы, конструкторы и т. Д., Если вы найдете время, чтобы выяснить, как это сделать.

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

Особенностью, которую я заметил больше всего при переходе этого кода с процедурного на OO, была инкапсуляция: как свойств, так и вызовов методов.

В дополнение к тому, что сказал aib, я бы сказал, что язык не является объектно-ориентированным, если только доступные стандартные библиотеки не являются объектно-ориентированными. Самый большой пример этого - PHP. Хотя он поддерживает все стандартные объектно-ориентированные концепции, тот факт, что такой большой процент стандартных библиотек не является объектно-ориентированным, означает, что практически невозможно написать ваш код объектно-ориентированным способом.

Неважно, что они вводят пространства имен, если все стандартные библиотеки все еще требуют от вас префикса всех вызовов функций с такими вещами, как mysql_ и pgsql_, когда в языке, который поддерживает пространства имен в реальном API, вы можете избавиться от функций с помощью mysql_ и просто добавьте "include system.db.mysql.*" вверху вашего файла, чтобы он знал, откуда взялись эти вещи.

Поддерживает классы, методы, атрибуты, инкапсуляцию, сокрытие данных, наследование, полиморфизм, абстракцию...?

Когда вы можете создавать классы, это объектно-ориентированный
например: java является объектно-ориентированным, javascript - нет, а C++ выглядит как "объектно-любопытный" язык

Объект: объект является хранилищем данных. Например, если MyList является объектом ShoppingList, MyList может записать ваш список покупок.

Класс: класс - это тип объекта. Многие объекты одного класса могут существовать; например, MyList и YourList могут быть объектами ShoppingList.

Метод: процедура или функция, которая работает с объектом или классом. Метод связан с определенным классом. Например, addItem может быть методом, который добавляет элемент в любой объект ShoppingList. Иногда метод связан с семейством классов. Например, addItem может работать с любым списком, из которых список покупок относится только к одному типу.

Наследование: класс может наследовать свойства от более общего класса. Например, класс ShoppingList наследует от класса List свойство хранения последовательности элементов.

Полиморфизм: возможность иметь один вызов метода работает с несколькими различными классами объектов, даже если эти классы нуждаются в разных реализациях вызова метода. Например, одна строка кода может вызывать метод "addItem" для каждого вида List, даже если добавление элемента в ShoppingList полностью отличается от добавления элемента в ShoppingCart.

Объектно-ориентированный: каждый объект знает свой собственный класс и какие методы манипулируют объектами в этом классе. Каждый ShoppingList и каждая ShoppingCart знает, какая реализация addItem применима к нему.

В этом списке единственное, что действительно отличает объектно-ориентированные языки от процедурных (C, Fortran, Basic, Pascal), это полиморфизм.

Источник: https://www.youtube.com/watch?v=mFPmKGIrQs4&list=PL-XXv-cvA_iAlnI-BQr9hjqADPBtujFJd

Несмотря на теоретические последствия, кажется,

"Любой язык, который имеет ключевое слово под названием" класс "":-P

Если язык разработан со средствами, специально предназначенными для поддержки объектно-ориентированного программирования (4 функции), то это объектно-ориентированный язык программирования.

  • Вы можете программировать в объектно-ориентированном стиле более или менее на любом языке. Объектно-ориентированным является код, а не язык.

  • Примерами реальных объектно-ориентированных языков являются Java, C#, Python, Ruby, C++. Кроме того, возможны расширения для предоставления объектно-ориентированных функций, таких как PHP, Perl и т. д.

  • Вы можете писать объектно-ориентированный код на C, но это не объектно-ориентированная программа. яз. Он не предназначен для этого (в этом весь смысл С++)

образец

Способность выражать реальные сценарии в коде.

foreach(House house in location.Houses)
{
 foreach(Deliverable mail in new Mailbag(new Deliverable[]
              {
              GetLetters(), 
              GetPackages(), 
              GetAdvertisingJunk()
              })
 {
    if(mail.AddressedTo(house))
    {
        house.Deliver(mail);
    }
 }
}

-

foreach(Deliverable myMail in GetMail())
{
    IReadable readable = myMail as IReadable;
    if ( readable != null )
    {
        Console.WriteLine(readable.Text);
    }
}

Зачем?

Чтобы помочь нам понять это более легко. Это имеет смысл в наших головах и при правильной реализации делает код более эффективным, может использоваться повторно и уменьшает количество повторений.

Для этого вам нужно:

  • Указатели / Ссылки, чтобы гарантировать, что это == это и это!= Это.
  • Классы для указания (например, Arm), которые хранят данные (int hairyness) и операции (Throw(IThrowable))
  • Полиморфизм (Наследование и / или Интерфейсы) для обработки определенных объектов в общем виде, чтобы вы могли читать книги, а также граффити на стене (оба реализуют IReadable)
  • Инкапсуляция, потому что яблоко не раскрывает свойство Atoms[]
Другие вопросы по тегам