Почему утверждают, что люди на c # не получают объектно-ориентированного программирования? (против класса) - PullRequest
14 голосов
/ 09 сентября 2008

Это привлекло мое внимание прошлой ночью.

В последнем ALT.NET Podcast Скотт Беллвер обсуждает, как в отличие от Ruby, такие языки, как c #, java et al. на самом деле не объектно-ориентированные, а предпочитают фразу «класс-ориентированный». Они очень смутно говорят об этом различии, не вдаваясь в подробности и не обсуждая плюсы и минусы.

Какая здесь реальная разница и насколько это важно? Какие еще языки тогда являются «объектно-ориентированными»? Это звучало довольно интересно, но я не хочу изучать Ruby, просто чтобы знать, что, если что-то мне не хватает.

Обновление : После прочтения некоторых ответов ниже кажется, что люди обычно соглашаются с тем, что речь идет о наборе утки. Но я не уверен, что понимаю до сих пор, хотя это утверждение о том, что это в конечном итоге все так сильно меняет. Особенно, если вы уже делаете правильный тдд со слабой связью, бла-бла-бла. Может кто-нибудь показать мне пример удивительной вещи, которую я мог бы сделать с ruby, которую я не могу сделать с c #, и которая иллюстрирует этот другой упорный подход?

Ответы [ 14 ]

23 голосов
/ 27 апреля 2009

В объектно-ориентированном языке объекты определяются путем определения объектов, а не классов, хотя классы могут предоставлять некоторые полезные шаблоны для конкретных определений cookie-резака данной абстракции. В языке, ориентированном на классы, как, например, C #, объекты должны быть определены классами, и эти шаблоны обычно консервируются и упаковываются и становятся неизменяемыми до выполнения. Это произвольное ограничение, заключающееся в том, что объекты должны быть определены до выполнения и что определения объектов являются неизменяемыми, не является объектно-ориентированной концепцией; он ориентирован на класс.

15 голосов
/ 09 сентября 2008

Комментарии, вводимые здесь утиной клавиатурой, больше связаны с тем, что Ruby и Python более динамические , чем C #. Это на самом деле не имеет ничего общего с природой.

Что (я думаю) Bellware подразумевает под этим, что в Ruby все является объектом. Даже класс. Определение класса является экземпляром объекта. Таким образом, вы можете добавлять / изменять / удалять поведение во время выполнения.

Другим хорошим примером является то, что NULL также является объектом. В ruby ​​все буквально объект. Наличие такого глубокого ОО во всем своем существе допускает некоторые забавные методы метапрограммирования, такие как method_missing.

10 голосов
/ 09 сентября 2008

IMO, это действительно чрезмерное определение «объектно-ориентированного», но они ссылаются на то, что Ruby, в отличие от C #, C ++, Java и др., Не использует , определяющий класс - - вы действительно только когда-либо работали непосредственно с объектами. И наоборот, в C #, например, вы определяете классы , которые затем вы должны создать в объекте с помощью нового ключевого слова. Ключевым моментом является то, что вы должны объявить класс в C # или описать его. Кроме того, в Ruby все - даже, например, числа - является объектом. В отличие от этого, C # все еще сохраняет концепцию типа объекта и типа значения. На самом деле это, я думаю, иллюстрирует точку зрения, которую они делают о C # и других подобных языках: объект тип и значение тип подразумевают систему тип , то есть целая система , описывающая типы , а не просто работа с объектами.

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

9 голосов
/ 09 сентября 2008

Есть три столба ООП

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

Если язык может выполнять эти три вещи, это язык ООП.

Я почти уверен, что аргумент языка X делает ООП лучше, чем язык А будет продолжаться вечно.

4 голосов
/ 17 октября 2008

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

Статический OO, как в C #, не имеет такого рода инкапсуляции. Массаж имеет , чтобы соответствовать существующему методу или свойству, в противном случае компилятор будет жаловаться. Однако динамические языки, такие как Smalltalk, Ruby или Python, поддерживают ОО на основе сообщений.

Таким образом, в этом смысле C # и другие статически типизированные OO-языки не являются истинными OO, так как им не хватает «истинной» инкапсуляции.

3 голосов
/ 18 сентября 2008

Обновление: это новая волна ... которая говорит о том, что все, что мы делали до сих пор, устарело ... Похоже, что это довольно много в подкастах и ​​книгах ... Возможно, это то, что вы слышали.

До сих пор мы занимались статическими классами, а не раскрыли мощь объектно-ориентированной разработки. Мы занимались разработкой на основе классов. Классы - это фиксированные / статические шаблоны для создания объектов. Все объекты класса созданы равными.

например. Просто чтобы проиллюстрировать то, о чем я болтаю ... позвольте мне взять фрагмент кода Ruby из скриншота 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-In (использование поведения без наследования классов) ..

Испытывая основные примитивы того, как мы думаем о проблемах, «настоящий ООП» в некотором смысле похож на «Матрицу» ... Вы продолжаете WTF в цикле. Как этот ... где базовый класс Контейнера может быть либо Массивом, либо Хэшем, в зависимости от того, на какой стороне 0,5 сгенерировано случайное число.

class Container < (rand < 0.5 ? Array : Hash)
end

Руби, javascript и новая бригада, похоже, являются первопроходцами в этом. Я все еще об этом ... читаю и пытаюсь разобраться в этом новом явлении. Кажется сильным .. слишком сильным .. Полезным? Мне нужно, чтобы мои глаза открылись немного больше. Интересные времена .. эти.

2 голосов
/ 09 сентября 2008

Я слушал только первые 6-7 минут подкаста, который вызвал ваш вопрос. Если они хотят сказать, что C # не является чисто объектно-ориентированным языком, это действительно правильно. Все в C # не является объектом (по крайней мере, примитивы - нет, хотя бокс создает объект, содержащий то же значение). В Ruby все является объектом. Дарен и Бен, похоже, рассмотрели все основы в своем обсуждении «типизации утки», поэтому я не буду повторять это.

Является ли это различие (все, что объект против всего, что не объект) материальным / значимым - вопрос, на который я не могу с готовностью ответить, потому что у меня недостаточно глубины в Ruby, чтобы сравнить его с C #. Те из вас, кто здесь знает Smalltalk (я не знаю, хотя хотелось бы), вероятно, с некоторым интересом смотрели на движение Ruby, так как это был первый чистый OO-язык 30 лет назад.

2 голосов
/ 09 сентября 2008

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

если он ходит как утка и крякает как утка, просто притворись, что это утка, и пни его.

В C #, Java и т. Д. Компилятор много размышляет о: разрешено ли выполнять эту операцию над этим объектом?

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

Например: в Python для реализации итерируемого объекта вам нужно только предоставить метод __iter__(), который возвращает объект, имеющий метод с именем next(). Вот и все, что нужно сделать: Нет реализации интерфейса (такой вещи нет). Нет подклассов. Просто говорю как утка / итератор.

РЕДАКТИРОВАТЬ: Это сообщение было проголосовано, пока я все переписал. Извините, никогда не буду делать это снова. Первоначальный контент содержал совет выучить как можно больше языков и не беспокоиться о том, что врачи думают / говорят о языке.

1 голос
/ 12 июля 2010

Вы спросили: «Может ли кто-нибудь показать мне пример удивительной вещи, которую я мог бы сделать с ruby, которую я не могу сделать с c #, и которая иллюстрирует этот другой упорный подход?»

Один хороший пример - активная запись, ORM, встроенная в рельсы. Классы модели динамически создаются во время выполнения на основе схемы базы данных.

1 голос
/ 17 июня 2009

Объектно-ориентированная концепция. Эта концепция основана на определенных идеях. Технические названия этих идей (на самом деле, скорее, принципы, которые развивались с течением времени и отсутствовали с первого часа), уже приведены выше, я не буду их повторять. Я скорее объясняю это как можно проще и нетехнически.

Идея ОО-программирования заключается в том, что существуют объекты. Объекты - это небольшие независимые объекты. Эти объекты могут иметь встроенную информацию или нет. Если у них есть такая информация, только сама сущность может получить к ней доступ или изменить ее. Объекты связываются друг с другом, отправляя сообщения друг другу. Сравните это с людьми. Человеческие существа - это независимые сущности, имеющие внутренние данные, хранящиеся в их мозге, и взаимодействующие друг с другом посредством общения (например, общение друг с другом). Если вам нужны знания из чужого мозга, вы не можете напрямую получить к ним доступ, вы должны задать ему вопрос, и он может ответить вам на это, рассказав вам то, что вы хотели знать.

И это в основном все. Это реальная идея, лежащая в основе ОО-программирования. Написание этих сущностей, определить связь между ними и заставить их взаимодействовать друг с другом, чтобы сформировать приложение. Эта концепция не связана с каким-либо языком. Это просто концепция, и если вы пишете свой код на C #, Java или Ruby, это не важно. С некоторой дополнительной работой эта концепция может быть реализована даже на чистом C, хотя это и функциональный язык, но он предлагает все, что вам нужно для концепции.

Различные языки в настоящее время приняли эту концепцию ОО-программирования, и, конечно, концепции не всегда равны. Например, некоторые языки допускают то, что запрещают другие языки. Теперь одним из понятий, которые вовлечены, является понятие классов. У некоторых языков есть классы, у некоторых нет. Класс - это образец того, как выглядит объект. Он определяет внутреннее хранилище данных объекта, он определяет сообщения, которые объект может понять, и, если есть наследование (которое не обязательно для ОО-программирования!), Классы также определяют, от какого другого класса (или классов если допускается множественное наследование), этот класс наследует (и какие свойства, если существует выборочное наследование). После того, как вы создали такой проект, вы можете создавать неограниченное количество объектов в соответствии с этим планом.

Однако в ОО-языках нет классов. Как строятся объекты? Ну, обычно динамически. Например. Вы можете создать новый пустой объект, а затем динамически добавить к нему внутреннюю структуру, например переменные экземпляра или методы (сообщения). Или вы можете продублировать уже существующий объект со всеми его свойствами, а затем изменить его. Или, возможно, объединить два объекта в новый. В отличие от языков, основанных на классах, эти языки очень динамичны, поскольку вы можете динамически генерировать объекты во время выполнения таким образом, о котором даже разработчик не задумывался, когда начинал писать код.

Обычно эта динамика имеет цену: чем динамичнее язык, тем больше объектов памяти (ОЗУ) будет потрачено впустую, и тем медленнее будет все, поскольку поток программы также чрезвычайно динамичен, и компилятору сложно генерировать эффективный код, если он не имеет шансов предсказать код или поток данных. JIT-компиляторы могут оптимизировать некоторые части этого во время выполнения, когда они знают поток программы, однако, поскольку эти языки настолько динамичны, поток программы может измениться в любое время, заставляя JIT отбрасывать все результаты компиляции и повторно компилировать тот же код снова и снова.

Но это крошечная деталь реализации - она ​​не имеет ничего общего с основным принципом ОО. Нигде не сказано, что объекты должны быть динамическими или изменяемыми во время выполнения. Википедия говорит это довольно хорошо:

Методы программирования могут включать такие функции, как сокрытие информации, абстракция данных, инкапсуляция, модульность, полиморфизм и наследование.

http://en.wikipedia.org/wiki/Object-oriented_programming

Они могут или могут не . Это все не обязательно. Обязательным является только наличие объектов и то, что у них должны быть способы взаимодействия друг с другом (иначе объекты были бы довольно бесполезны, если бы они не могли взаимодействовать друг с другом).

...