Почему утверждение о том, что люди С# не получают объектно-ориентированного программирования? (против класса)
Это привлекло мое внимание прошлой ночью.
В последнем ALT.NET Podcast Scott Bellware обсуждает, как в отличие от Ruby, такие языки, как С#, java и др. на самом деле не объектно ориентированы, а предпочитают фразу "класс-ориентированная". Они говорят об этом различии в очень расплывчатых выражениях, не вдаваясь в подробности и не обсуждая плюсы и минусы.
В чем тут разница и насколько это важно? Какие другие языки тогда являются "объектно-ориентированными"? Это звучало довольно интересно, но я не хочу изучать Ruby, чтобы знать, что, если что-то мне не хватает.
Обновление. После прочтения некоторых из приведенных ниже ответов кажется, что люди в целом согласны с тем, что ссылка на утиную печать. То, что я не уверен, я все еще понимаю, хотя это утверждение, что это в конечном итоге сильно изменило все это. Особенно, если вы уже делаете правильный tdd со свободной связью blah blah blah. Может ли кто-нибудь показать мне пример чудесной вещи, которую я мог бы сделать с рубином, который я не могу сделать с С#, и это иллюстрирует этот подход с использованием oop?
Ответы
Ответ 1
Комментарии с комментариями утки объясняются тем, что Ruby и Python более динамичны, чем С#. Это не имеет ничего общего с OO Nature.
Что (я думаю) Bellware означает, что в Ruby все является объектом. Даже класс. Определение класса - это экземпляр объекта. Таким образом, вы можете добавить/изменить/удалить поведение во время выполнения.
Другим хорошим примером является то, что NULL также является объектом. В рубине все это ЛИТЕРАТУРНЫЙ объект. Наличие такого глубокого OO во всем этом позволяет использовать некоторые интересные методы метапрограммирования, такие как method_missing.
Ответ 2
В объектно-ориентированном языке объекты определяются путем определения объектов, а не классов, хотя классы могут предоставить некоторые полезные шаблоны для конкретных определений cookie-cutter для данной абстракции. Например, в классе-ориентированном языке, например С#, объекты должны быть определены классами, и эти шаблоны обычно консервируются и упаковываются и становятся неизменными перед временем выполнения. Это произвольное ограничение того, что объекты должны быть определены до времени выполнения и что определения объектов неизменяемы, не является объектно-ориентированной концепцией; он ориентирован на класс.
Ответ 3
IMO, он действительно чрезмерно определяет "объектно-ориентированный", но то, что они имеют в виду, - это то, что Ruby, в отличие от С#, С++, Java и других, не использует определение класса - вы действительно только когда-либо работаете непосредственно с объектами. И наоборот, в С#, например, вы определяете классы, которые затем должны создавать объекты на основе нового ключевого слова. Ключевым моментом является то, что вы должны объявить класс на С# или описать его. Кроме того, в Ruby все - даже цифры, например, - это объект. Напротив, С# по-прежнему сохраняет концепцию типа объекта и типа значения. Это на самом деле, я думаю, иллюстрирует то, что они делают о С# и других подобных языках - тип объекта и тип значения подразумевают систему типов, то есть у вас есть целая система описания типов, а не просто работа с объектами.
Концептуально, я думаю, что дизайн OO - это то, что обеспечивает абстракцию для использования в сложных системах в наши дни. Язык - это инструмент, используемый для реализации дизайна OO - некоторые делают его более естественным, чем другие. Я бы все же утверждал, что из более распространенного и более широкого определения С# и другие все еще являются объектно-ориентированными языками.
Ответ 4
Есть три столпа ООП
- Герметизация
- Наследование
- Полиморфизм
Если язык может выполнять эти три вещи, это язык ООП.
Я уверен, что аргумент языка X делает ООП лучше, чем язык А будет продолжаться вечно.
Ответ 5
OO иногда определяется как ориентированный на сообщения. Идея состоит в том, что вызов метода (или доступ к свойствам) - это действительно сообщение, отправленное другому объекту. То, как возвращающий объект обрабатывает сообщение, полностью инкапсулируется. Часто сообщение соответствует методу, который затем выполняется, но это всего лишь деталь реализации. Например, вы можете создать обработчик catch-all, который выполняется независимо от имени метода в сообщении.
Static OO, как в С#, не имеет такого типа инкапсуляции. Массаж должен соответствовать существующему методу или свойству, иначе компилятор будет жаловаться. Однако динамические языки, такие как Smalltalk, Ruby или Python, поддерживают "OO на основе сообщений".
Итак, в этом смысле С# и другие статически типизированные языки OO не являются истинными OO, sine thay не хватает "истинной" инкапсуляции.
Ответ 6
Обновление: его новая волна.., которая предлагает все, что мы делали до сих пор, это passe.. Кажется, что немного подпирает подкасты и книги. Возможно, это то, что вы слышали.
До сих пор мы занимались статическими классами, а не unleashed мощью объектно-ориентированного развития. Мы делали "основанные на классе разработчики". Классы - это фиксированные/статические шаблоны для создания объектов. Все объекты класса создаются равными.
например. Просто для того, чтобы проиллюстрировать, о чем я болтал... позвольте мне взять фрагмент кода Ruby из scrapencast PragProg. У меня была привилегия смотреть.
"Основанная на прототипе разработка" стирает линию между объектами и классами. Разница не существует.
animal = Object.new # create a new instance of base Object
def animal.number_of_feet=(feet) # adding new methods to an Object instance. What?
@number_of_feet = feet
end
def animal.number_of_feet
@number_of_feet
end
cat = animal.clone #inherits 'number_of_feet' behavior from animal
cat.number_of_feet = 4
felix = cat.clone #inherits state of '4' and behavior from cat
puts felix.number_of_feet # outputs 4
Идея - это более мощный способ наследования состояния и поведения, чем традиционное наследование на основе классов. Это дает вам больше гибкости и контроля в определенных "специальных" сценариях (которые я еще не понял). Это позволяет использовать такие вещи, как Mix-ins (повторное использование поведения без наследования классов).
Вызывая основные примитивы того, как мы думаем о проблемах, "истинный ООП" походит на "Матрицу" в некотором смысле... Вы продолжаете идти в WTF. Как и тот, где базовый класс Container может быть либо массивом, либо хешем, на основании которого 0,5 генерируется случайное число.
class Container < (rand < 0.5 ? Array : Hash)
end
Ruby, javascript и новая бригада, похоже, являются первопроходцами этого. Я все еще нахожусь на этом... читаю и пытаюсь понять это новое явление. Кажется, это мощная.. слишком мощная.. Полезная? Мне нужно, чтобы мои глаза открылись еще немного. Интересные времена.. эти.
Ответ 7
Может быть, они намекают на разницу между типизацией уток и иерархиями классов?
если он ходит как утка и шарлатанцы, как утка, просто притворись, что это утка и ударишь ее.
В С#, Java и т.д. компилятор много беспокоится о: разрешено ли вам выполнять эту операцию на этом объекте?
Объектно-ориентированный и ориентированный на классы может поэтому означать: беспокоит ли язык об объектах или классах?
Например: в Python для реализации итерационного объекта вам нужно только указать метод __iter__()
, который возвращает объект с методом с именем next()
. Это все, что ему нужно: нет реализации интерфейса (нет такой вещи). Нет подкласса. Просто говорите, как утка/итератор.
РЕДАКТИРОВАТЬ: Этот пост был сохранен, пока я переписал все. Извините, больше этого не повторится. Исходный контент включал советы по изучению как можно большего количества языков, а также к тому, чтобы беспокоиться о том, что говорят врачи-лингвисты о языке.
Ответ 8
Я только слушал первые 6-7 минут подкаста, которые вызвали ваш вопрос. Если их намерение состоит в том, чтобы сказать, что С# не является чисто объектно-ориентированным языком, это действительно правильно. Все в С# не является объектом (по крайней мере, примитивов нет, хотя бокс создает объект, содержащий одно и то же значение). В Ruby все является объектом. Дарен и Бен, похоже, рассмотрели все основы в обсуждении "утиной печати", поэтому я не буду повторять его.
Независимо от того, является ли эта разница (все объект против всего, что не является объектом) существенным/значимым, это вопрос, на который я не могу легко ответить, потому что у меня недостаточно глубины в Ruby, чтобы сравнить его с С#. Те из вас, кто здесь знает Smalltalk (я не хочу, хотя бы хотел, чтобы я это сделал), вероятно, смотрели на движение Ruby с некоторым развлечением, так как это был первый чистый OO-язык 30 лет назад.
Ответ 9
Это был абстрактно-подкаст!
Но я вижу, что они получают - они просто ослеплены Руби Спирлом. Ruby позволяет вам делать то, что программисты на основе C и Java даже не думали о + комбинациях этих вещей, позволяя вам достичь невероятных возможностей.
Добавление новых методов во встроенный класс String coz вы чувствуете, как это, прохождение вокруг неназванных блоков кода для других, чтобы выполнить, mixins... Обычные люди не используются для объектов, слишком сильно изменяющих шаблон шаблона.
Его совершенно новый мир там наверняка.
Что касается парней С#, которые не являются OO достаточно... не принимайте это близко к сердцу. Просто воспринимайте это как материал, который вы говорите, когда вас обманывают слова. Ruby делает это для большинства людей.
Если бы мне пришлось порекомендовать один язык для людей, чтобы учиться в текущем десятилетии.. это будет Ruby. Я рад, что сделал. Хотя некоторые люди могут претендовать на Python. Но это похоже на мое мнение.. человек!: D
Ответ 10
Я не думаю, что это особенно касается печатания уток. Например, С# поддерживает ограниченный набор утиных слов - пример будет заключаться в том, что вы можете использовать foreach для любого класса, который реализует MoveNext и Current.
Концепция утиного ввода совместима со статически типизированными языками, такими как Java и С#, это в основном расширение отражения.
Это действительно случай статической и динамической типизации. Оба являются правильными-OO, насколько это возможно. Вне академических кругов это действительно не стоит обсуждать.
Код мусора может быть записан в любом из них. Отличный код может быть написан в любом из них. Там абсолютно ничего функционального, что одна модель может сделать, а другая не может.
Реальная разница в характере кодирования. Статические типы уменьшают свободу, но преимущество в том, что все знают, с чем они имеют дело. Возможность менять экземпляры "на лету" очень эффективна, но стоимость заключается в том, что становится трудно узнать, что вы делаете.
Например, для Java или С# intellisense легко - среда IDE может быстро создать список возможных возможностей. Для Javascript или Ruby это становится намного сложнее.
Для некоторых вещей, например, для создания API, с которым будет компилироваться кто-то другой, существует реальное преимущество в статической типизации. Для других, например, для быстрого создания прототипов преимущество переходит в динамическое.
Это стоит понимать как в вашем инструменте инструментов, так и в не столь важном, как понимание того, что вы уже используете на реальной глубине.
Ответ 11
Объектно-ориентированная концепция. Эта концепция основана на определенных идеях. Технические имена этих идей (на самом деле скорее принципы, которые эволюционировали с течением времени и не были там с первого часа) уже были приведены выше, я не буду повторять их. Я скорее объясняю это как простой и нетехнический, как я могу.
Идея программирования OO заключается в том, что существуют объекты. Объекты - это небольшие независимые объекты. Эти объекты могут иметь встроенную информацию, иначе они могут отсутствовать. Если у них есть такая информация, только сам объект может получить к ней доступ или изменить ее. Сущности взаимодействуют друг с другом, отправляя сообщения друг другу. Сравните это с людьми. Люди - это независимые сущности, имеющие внутренние данные, хранящиеся в их мозгу, и взаимодействующие друг с другом посредством общения (например, общения друг с другом). Если вам нужны знания от кого-то другого мозга, вы не можете напрямую обращаться к нему, вы должны задать ему вопрос, и он может ответить на это вам, сообщив вам, что вы хотели знать.
И это в основном это. Это реальная идея программирования OO. Написав эти сущности, определите связь между ними и объедините их, чтобы сформировать приложение. Эта концепция не связана ни с одним языком. Это просто концепция, и если вы пишете свой код на С#, Java или Ruby, это не важно. С некоторой дополнительной работой эта концепция может быть даже выполнена в чистом C, хотя это функциональный язык, но он предлагает все, что вам нужно для концепции.
В настоящее время разные языки используют эту концепцию программирования ОО, и, конечно, понятия не всегда равны. Некоторые языки позволяют, например, запрещать другие языки. В настоящее время одной из концепций является концепция классов. Некоторые языки имеют классы, некоторые - нет. Класс - это проект, как выглядит объект. Он определяет внутреннее хранение данных объекта, он определяет сообщения, которые может понять объект, и если есть наследование (что не обязательно для программирования OO!), Классы также определяют, из какого другого класса (или классов, если допускается множественное наследование) этот класс наследует (и какие свойства, если существует выборочное наследование). Создав такой проект, вы можете создать неограниченное количество объектов в соответствии с этим планом.
Есть языки OO, у которых нет классов. Как объекты строятся? Ну, обычно динамически. Например. вы можете создать новый пустой объект, а затем динамически добавить внутреннюю структуру, такую как переменные экземпляра или методы (сообщения). Или вы можете дублировать уже существующий объект со всеми его свойствами, а затем изменять его. Или, возможно, объединить два объекта в новый. В отличие от языков на основе классов эти языки очень динамичны, так как вы можете генерировать объекты динамически во время выполнения способами, о которых вы даже не задумывались разработчиком при начале написания кода.
Обычно эта динамика имеет цену: чем более динамичным является язык, тем больше объектов памяти (ОЗУ) будет тратить время, а все медленнее все становится так же, как и поток программы, а также очень сложно компилятору генерировать эффективный код, если он не имеет возможности прогнозировать кодекс или поток данных. Компиляторы JIT могут оптимизировать некоторые части этого во время выполнения, как только они знают поток программы, однако, поскольку эти языки настолько динамичны, поток программы может измениться в любое время, заставляя JIT удалять все результаты компиляции и повторно компилировать один и тот же код снова и снова.
Но это крошечная деталь реализации - она не имеет ничего общего с основным принципом OO. Нигде не сказано, что объекты должны быть динамическими или должны быть изменены во время выполнения. Википедия говорит это довольно хорошо:
Методы программирования могут включать такие функции, как скрытие информации, абстракция данных, инкапсуляция, модульности, полиморфизма и наследование.
http://en.wikipedia.org/wiki/Object-oriented_programming
Они могут или не могут. Все это не обязательно. Обязательным является только наличие объектов и что у них должны быть способы взаимодействия друг с другом (иначе объекты были бы бесполезны, если они не могут взаимодействовать друг с другом).
Ответ 12
Вы спросили: "Может ли кто-нибудь показать мне пример замечательной вещи, которую я мог бы сделать с рубином, который я не могу сделать с С#, и это иллюстрирует этот подход?"
Одним хорошим примером является активная запись, ORM встроенная в рельсы. Классы моделей динамически создаются во время выполнения на основе схемы базы данных.
Ответ 13
Я возьмусь за это.
Python и Ruby напечатаны в стиле утка. Чтобы создать любой поддерживаемый код на этих языках, вам в значительной степени придется использовать тестовую разработку. Таким образом, очень важно, чтобы разработчик легко вставлял зависимости в свой код, не создавая гигантскую поддерживающую структуру.
Успешная инъекция зависимостей зависит от наличия довольно хорошей объектной модели. Эти две части являются двумя сторонами одной и той же монеты. Если вы действительно понимаете, как использовать ООП, тогда вы должны по умолчанию создавать проекты, в которых зависимости можно легко вводить.
Поскольку инъекция зависимостей проще в динамически типизированных языках, разработчики Ruby/Python считают, что их язык лучше понимает уроки OO, чем другие статически типизированные копии.
Ответ 14
На самом деле это, вероятно, связано с тем, что эти люди видят, как другие делают в С# и java, в отличие от С# и java, поддерживающих OOP. Большинство языков могут использоваться в различных парадигмах программирования. Например, вы можете написать процедурный код в С# и схеме, и вы можете выполнять функциональное программирование в java. Это больше о том, что вы пытаетесь сделать и что поддерживает язык.