Является ли переменная объектом в ООП?

Рейтинг: 32Ответов: 9Опубликовано: 25.03.2011

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

Ответы

▲ 18Принят

В С это не так — там просто нет понятия "объект". =)


Объект отличается от не объекта тем, что он имеет сложное и активное внутреннее устройство.

Не объект всего лишь является отображением участка памяти. Будь то просто число, указатель, некий обычный массив или структура. Действия над ними — просто оперирование данными в памяти. Взял, изменил, положил обратно. Вне зависимости от содержимого участка памяти. И переменная эта никаких возмущений в эти действия не вносит.

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

Моё мнение — в компилируемом и статически типизируемом языке обычно (но вовсе не обязательно) простые переменные не являются объектами.

В C# практически любая переменная — объект (как справедливо заметили, за исключением указателей). Ввиду того, что типы int, string, char и все иные — это, так сказать, синонимы соответствующих классов: System.Int32, System.String, System.Char. В С++ — нет.

А в динамически типизируемом языке у каждой переменной, как минимум, есть скрытые свойства - тип, например. И действия совершаются различные в зависимости от содержимого оного свойства. И оператор + числа сложит, строки склеит и т.д.

▲ 15

Он утверждает, что в ООП переменная - это не объект, во всяком случае в C.

В Си нету объектов, Си является процедурным языком. Если имели ввиду C++, то ответ тот же — значение переменной не обязательно является объектом.

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

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

В C++ это так из-за того что он основан на Си и обязан играть по его правилам.

Во многих объектно-ориентированных языках это так. (Python, Ruby, Smalltalk). В Java также как и в C++ базовые типы (int) не являются объектами, но в случае Java для них есть объекты-аналоги(Integer).

▲ 12

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

SomeObject x; // Создание переменной x.
              // Сравните с: Environment.getCurrent().createVariable("x")
x = 20;       // Помещение значения в переменную.
              // Сравните с: Environment.getCurrent().lookupVariable("x").assign(20)
x;            // Извлечение значения переменной.
              // Сравните с: Environment.getCurrent().lookupVariable("x").getValue()

А операция удаления слота и вовсе не доступна в явном виде программисту, как могла бы быть:

// Environment.getCurrent().free("x")

Чтобы лучше понять, как бы выглядела работа с переменными, будь они объектами, рассмотрим похожую проблему. Зададимся вопросом: а являются ли функции (или методы) объектами? Для Java/C#/C++ ответ отрицательный (если анонимные функции в C# имеют объектный интерфейс, просьба меня поправить). Но, скажем, в языке Scala, функции (и методы) и правда являются объектами, иными словами, они имеют объектные интерфейсы. К примеру, создадим новую функцию для двух аргументов, которую положим в переменную sum:

scala> val sum = (x: Int, y: Int) => x + y
sum: (Int, Int) => Int = <function2>

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

scala> sum.getClass
res5: java.lang.Class[_ <: (Int, Int) => Int] = class $anonfun$1

Вызвать (применить) функцию можно традиционным способом:

scala> sum(5,6)
res6: Int = 11

А можно и с помощью объектного интерфейса:

scala> sum.apply(5,6)
res7: Int = 11

Создадим еще одну функцию, на этот раз с помощью явного создания объекта на основе интерфейса Function2, представляющего функции для двух аргументов:

scala> val mul = new Function2[Int,Int, Int] { def apply(x: Int, y: Int) = x * y }
mul: java.lang.Object with (Int, Int) => Int = <function2>

Полученная функция также является обычным объектом с методом apply:

scala> mul.apply(5,9)
res8: Int = 45

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

scala> val sum2 = sum.curried
sum2: Int => Int => Int = <function1>

scala> val inc = sum2(1)
inc: Int => Int = <function1>

scala> List(inc(7), inc(20), inc(35))
res10: List[Int] = List(8, 21, 36)

scala> val dec = sum2(-1)
dec: Int => Int = <function1>

scala> List(dec(7), dec(20), dec(35))
res11: List[Int] = List(6, 19, 34)

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

▲ 10

Почему я не могу комментировать? :)

Ну да ладно. Тут выше написали, что

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

Так вот это жуткий-жуткий бред. В C# есть сущности, не неследуемые от Object. Это указатели, интерфейсы, параметры типов в дженериках.

▲ 7

Столь долгое обсуждение навело на мысль: а извините, пожалуйста, а где вы видели ООП язык?? ООП не более чем подход, но никак уж не язык, тогда есть АОП язык что ли? Когда вы реализуете ООП на каком-либо языке, это не значит, что это язык ООП. Если подход ООП, там объекты, но если ООП в решении кураг задач и нафиг не надо, тогда какие объекты? Умение определять, где ООП надо, а где нет, тоже, кстати, дело не из простых.

▲ 6

Я утверждаю, что переменная - это в корне тоже объект определенного типа в любом объктно-ориентированном языке

Я склонен думать именно так. Просто типы объектов могут быть встроенные в язык (long int, например), а могут быть пользовательскими (собственно, классы, например).

См. еще Чем отличается экземпляр класса от объекта класса?>тут

Отмечу, что в C/C++ объект - все, что имеет адрес в памяти. Т.е. является lvalue. Переменные ссылочного типа (напр., &int) - объектами по сути не являются!?!?

PS: с каждым разом все убеждаюсь в мнении, что C++ язык непростой, а представляющий из себя мешанину различных концепций...

▲ 5

Тут выше писали про то, что

В C# любая переменная - объект. Ввиду того, что типы int, string, char и все иные - это, так сказать, синонимы соответствующих классов: System.Int32, System.String, System.Char. В С++ - нет.

Так вот, это неправда. Я думаю, ни для кого не секрет, что в C# можно вполне сносно работать с указателями. И указатели при этом объектами не являются.

▲ 5

Объект - это такой тип данных, у которого имеются такие элементы, как поля данных и методы, и который характеризуется свойствами: инкапсуляция и наследование. Обычные переменные этими свойствами обладают? Если обладают, то ДА, это объекты. Если нет, то нет. Кроме того, в описании некоторых языков четко прописано, что переменные обычных типов объектами не являются. Пример - Java.

▲ 4

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

Паради́гма программи́рования — это совокупность идей и понятий, определяющих стиль написания программ.

Объект — некоторая сущность в виртуальном пространстве, обладающая определённым состоянием и поведением, имеет заданные значения свойств (атрибутов) и операций над ними (методов)[1]. Как правило, при рассмотрении объектов выделяется то, что объекты принадлежат одному или нескольким классам, которые в свою очередь определяют поведение (являются моделью) объекта.

Переме́нная в императивном программировании — поименованная, либо адресуемая иным способом область памяти, адрес которой можно использовать для осуществления доступа к данным.

Мой ответ "Переменная, даже в языке поддерживающем ООП, может не быть объектом. Чаще всего (НЕ ВСЕГДА!) переменные типа int, float, char это базовые типы, которые не являются объектами."