Что делает язык объектно-ориентированным?
Поскольку спорить без содержательных терминов бессмысленно, я решил указать на слона в комнате и спросить: что именно делает язык "объектно-ориентированным"? Здесь я не ищу ответ из учебника, а на основе вашего опыта работы с ОО-языками, которые хорошо работают в вашей области, какой бы она ни была.
Смежный вопрос, который может помочь ответить первым: что такое архетип объектно-ориентированных языков и почему?
16 ответов
Определения для объектно-ориентации - это, конечно, огромное количество червей, но вот мои 2 цента:
Для меня Object-Orientation - это все, что связано с объектами, которые отправляют сообщения. Для меня это самая важная черта объектно-ориентированного языка.
Если бы мне пришлось составить упорядоченный список всех функций, которые должен иметь объектно-ориентированный язык, это выглядело бы так:
- Объекты, отправляющие сообщения другим объектам
- Все является объектом
- Позднее связывание
- Подтип Полиморфизм
- Наследование или что-то такое же выразительное, как делегирование
- Инкапсуляция
- Сокрытие информации
- абстракция
Очевидно, что этот список очень спорный, поскольку он исключает большое разнообразие языков, которые широко рассматриваются как объектно-ориентированные, такие как 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[]