Какие функции необходимы для объектной ориентации?

9

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

Например, посмотрите на следующий код C:

SDL_Surface* screen = SDL_SetVideoMode( 640, 480, 16, SDL_HWSURFACE);
SDL_FreeSurface( screen );

или код, обсуждаемый здесь .

Теперь вышеприведенный код не использует наследование, полиморфизм времени выполнения (?), Виртуальные функции и т. Д. Но мне кажется, что это ООП.

Является ли Object-Orientation простым написанием кода, основанного на создаваемых и разрушаемых структурах данных, таких как объекты, классы, структуры и т. Д., Для которых не требуется какой-либо особый шаблон или функции, предоставляемые языком программирования или библиотекой ?

ApprenticeHacker
источник
2
ООП обычно требует объектов . Однако можно написать код, который выглядит ООП на большинстве языков (я сомневаюсь, что вы можете сказать «эта сборка выглядит ООП»)
Raynos
Приведенный выше код не использует оператор if или цикл . Он не использует умножение или сложение. Вы не можете использовать две строки кода и список вещей, которые не показаны, чтобы сделать какое-либо суждение вообще. Из этих двух строк кода я могу сделать вывод, что это строго ленивый функциональный язык программирования, а не ОО-язык. Использование двух строк кода в качестве части обобщения не является реальным вопросом.
С.Лотт
Ссылка также включаются в приведенном выше коде , который я судил на. Также обратите внимание, что это не суждение , я спрашиваю вас, можно ли это считать ООП.
ApprenticeHacker
Тривиальный ответ - да . Моя точка зрения такова. Вы не можете - из примеров кода - принять решение об ООП. Это тривиальный вопрос определения. Либо язык определяется как язык ООП, либо нет. Любые данные примеры кода могут не требовать всех функций ООП. Действительно, ООП-код может использовать очень и очень мало функций. В Python, например, 1+2действительно является объектно-ориентированным. Это конструктор, который строит новый объект из двух существующих объектов. Использование примеров кода ничего не показывает.
С.Лотт
Что плохого в использовании этого определения и сравнении его с языком (не двумя примерами кода)? en.wikipedia.org/wiki/…
С.Лотт

Ответы:

11

По словам Алана Кея, который придумал термин «объектно-ориентированный»,

Для меня ООП означает только обмен сообщениями, локальное хранение и защиту, а также сокрытие процесса состояния и крайнюю позднюю привязку всех вещей. Это можно сделать в Smalltalk и в LISP. Возможно, есть другие системы, в которых это возможно, но я не знаю о них.

Обмен сообщениями (как реализовано в Smalltalk) является концепцией, сравнимой с полиморфизмом, но более мощной (по крайней мере, чем полиморфизм, поддерживаемый C ++ или Java). Это может быть сделано на всех языках, но довольно болезненно, если не поддерживается непосредственно языком. По сути, это означает, что объекты могут отправлять друг другу сообщения, содержащие что-либо, amd может реагировать, как они хотят, на сообщения, которые они получают. Чтобы полностью поддерживать обмен сообщениями, у объектов должен быть способ гибко реагировать на сообщения, не перечисляя их в исходном коде (что, в основном, и делают определения методов / функций).

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

поздняя привязка всех вещей - скользящая шкала, в которой C действительно далек от видения Кей (как и C ++, в то время как Java гораздо ближе). Может быть подделан (см. COM), но это будет боль в использовании.

Обратите внимание, как Кей не упоминает о наследовании . В том же письме он написал

Мне не понравилось, как Simula I или Simula 67 наследовали (хотя я думал, что Nygaard и Dahl были просто потрясающими мыслителями и дизайнерами). Поэтому я решил оставить наследование как встроенную функцию, пока не понял, что это лучше

Майкл Боргвардт
источник
4
Как именно Java и C # ближе к позднему связыванию, чем C ++?
fredoverflow
@FredOverflow: Java лениво загружает определения классов во время выполнения, когда они впервые используются, и делает это неявно через чрезвычайно гибкий механизм, который позволяет легко добавлять новые классы или даже генерировать их на лету. C ++ требует, чтобы вы повторно связали свой исполняемый файл или явно загрузили библиотеки. Ситуация с C # кажется менее ясной, чем я думал, поэтому я удалил ссылку на ti.
Майкл Боргвардт
5

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

Таким образом, любой язык, который может каким-либо образом моделировать объекты (объекты, которые содержат как данные, так и код) и инкапсуляцию, может использоваться для ООП. Например, в C вы можете использовать указатели функций для хранения функций в структурах, и вы можете использовать файловую систему заголовка / исходного кода для реализации инкапсуляции. Это не удобно, но достаточно сделать ООП. Вы, вероятно, даже можете согнуть что-то вроде Haskell или ML для выполнения ООП, и я не удивлюсь, если кто-нибудь сможет придумать способ выполнения ООП в сборке.

Однако на практике язык можно назвать «объектно-ориентированным», если он предоставляет полный набор синтаксических функций для явного объектно-ориентированного программирования. Как правило, это означает, что такой язык должен иметь: * понятие объекта * понятие вызова метода или передачи сообщений * удобный и простой способ управления доступом к элементам объекта * удобный и простой способ определения интерфейсов

Следовательно, я бы назвал кусок кода объектно-ориентированным, если он придерживается принципов ООП и использует доступный синтаксис ООП.

Кстати, ваш пример кода, вероятно , использует полиморфизм и виртуальные функции, хотя синтаксис C не делает это очевидным. Я не эксперт по SDL, но я ожидаю, что SDL_surfaceу меня будет возможность представлять различные типы поверхностей, каждая со своим собственным конкретным набором реализаций. код, но интерфейс (функции, которые принимают SDL_surface*в качестве аргумента) остается прежним. Точно так же, он также реализует инкапсуляцию: вы не можете получить прямой доступ к базовому представлению поверхности, вам нужно пройти через функции, которые знают, как обрабатывать SDL_surface, потому что это все, что у вас есть. Это хороший пример того, как вы делаете ООП в C.

tdammers
источник
Абстрактные типы данных, однако, моделирование данных и инкапсуляция не являются уникальными для ОО (как вы кратко упомянули сами). Я бы предпочел описывать ОО на основе его более уникальных возможностей (динамическое связывание вызовов методов, полиморфизм через вызовы указанных методов и т. Д.)
hugomg
4

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

Конкретный синтаксис для реализации ОО не является ключом, который определяет, является ли язык ОО или нет. Например, Smalltalk и C # имеют разные синтаксисы, но оба являются языками ОО (в разной степени). Ключ в том, сохраняет ли данный язык философию (см. Выше) и обеспечивает ли он необходимые средства для имплантации.

Без шансов
источник
2

Когда я был студентом, меня учили, что объектно-ориентированное программирование стоит на трех столпах:

  • инкапсуляция ,
  • полиморфизм и
  • наследование .

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

Обратите внимание, что это описывает набор функций, а не синтаксис . Следовательно, нужно ли вам писать

type obj; // or type obj = new type;
obj.func(arg);

или

type* ptr = create_type();
func(ptr, arg); 

не имеет значения

Таким образом, вы действительно можете программировать в соответствии с объектно-ориентированной парадигмой на C. Но язык не поддерживает этого, что делает его довольно болезненным упражнением. Вот почему C не считается объектно-ориентированным языком.

SBI
источник
2
Обучение этим «столпам», вероятно, принесло миру больше вреда, чем пользы. Инкапсуляция это хорошо, но это все.
tdammers
1
Они в этом списке, поэтому они, кажется, широко приняты: en.wikipedia.org/wiki/…
S.Lott
Можете ли вы объяснить, почему полиморфизм и наследование плохи?
MathAttack
@MathAttack: ты со мной разговариваешь ? Потому что я, конечно, так не сказал.
ВОО
1
@missingno: Что-то не обязательно должно быть уникальным для какой-то парадигмы, чтобы считаться важным для различения парадигмы. Инкапсуляция больше не должна быть уникальной для ООП, поскольку функции должны быть уникальными для структурированного программирования.
'15
2

Вы можете делать ОО на любом приличном языке общего назначения.

Это легче сделать это в «ОО» языке, потому что у вас есть идиоматические конструкции доступны и не должны прибегать к чему - то , как OO в C - что это возможно, но и страшен.

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

Joonas Pulakka
источник
2

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

Две основные другие характеристики, связанные с ОО-языками, были предоставлены не ОО-языками:

  • Инкапсуляция довольно хорошо обеспечена Ada83;
  • Наследование обеспечивается Обероном (Оберон интересен, Вирт хотел предоставить ОО-язык с как можно меньшим количеством ошибок, но ему пришлось пересмотреть свою концепцию, чтобы получить один - Оберон-2 - ОО).
AProgrammer
источник
1

Ориентация объекта определяется как

также проверьте записи википедии. это те особенности, которые язык должен обеспечивать, чтобы он был определен как объектно-ориентированный.

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

относительно вашего последнего вопроса ответ, вероятно, да. объектно-ориентированный в основном просто действует на методы объектов и передает эти объекты в качестве параметров.

Махач
источник
3
Определено кем?
Майкл Боргвардт