Что такое объекты «первого класса»?

195

Когда объекты или что-то еще называют «первоклассным» в данном языке программирования и почему? Чем они отличаются от языков, на которых их нет?

РЕДАКТИРОВАТЬ. Когда кто-то говорит «все является объектом» (как в Python), действительно ли он имеет в виду, что «все первоклассно»?

Федерико А. Рампони
источник
1
Можно ли передать этот вопрос программистам.SE? Или там тоже было бы несоответствие? Думаю, это хороший вопрос. Просто не могу сказать, какой форум подойдет ему лучше всего.
Shashank Sawant
17
Проголосовали за повторное открытие ... к сожалению, похоже, что он был закрыт людьми, которые не программируют, это явно по теме: /
djechlin

Ответы:

180

Короче говоря, ограничений на использование объекта нет. Он такой же, как и любой другой объект.

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

В зависимости от языка это может означать:

  • быть выраженным как анонимное буквальное значение
  • можно хранить в переменных
  • сохраняются в структурах данных
  • имеющий внутреннюю идентичность (независимо от имени)
  • быть сопоставимым на равенство с другими объектами
  • быть переданным в качестве параметра процедуры / функции
  • подлежат возврату в результате выполнения процедуры / функции
  • быть конструктивным во время выполнения
  • можно распечатать
  • быть читаемым
  • передаваться между распределенными процессами
  • возможность хранения вне запущенных процессов

Источник .

Однако в C ++ сами функции не являются объектами первого класса:

  • Вы можете переопределить оператор '()', сделав возможным использование объектной функции первого класса.
  • Указатели функций первоклассные.
  • boost bind, lambda и function предлагают функции первого класса

В C ++ классы - это не объекты первого класса, а экземпляры этих классов. В Python и классы, и объекты являются объектами первого класса. (См. Этот ответ для получения дополнительных сведений о классах как объектах).

Вот пример функций первого класса Javascript:

// f: function that takes a number and returns a number
// deltaX: small positive number
// returns a function that is an approximate derivative of f
function makeDerivative( f, deltaX )
{
    var deriv = function(x)
    { 
       return ( f(x + deltaX) - f(x) )/ deltaX;
    }
    return deriv;
}
var cos = makeDerivative( Math.sin, 0.000001);
// cos(0)     ~> 1
// cos(pi/2)  ~> 0

Источник .

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

Что касается редактирования:

РЕДАКТИРОВАТЬ. Когда кто-то говорит «все является объектом» (как в Python), действительно ли он имеет в виду, что «все первоклассно»?

Термин «объект» может использоваться свободно и не означает, что он первоклассный. И, вероятно, было бы разумнее назвать всю концепцию «сущностями первого класса». Но в Python они действительно стремятся сделать все первоклассным. Я считаю, что намерение человека, сделавшего ваше заявление, было первоклассным.

Брайан Р. Бонди
источник
3
Вы можете привести несколько примеров не «первоклассных» объектов?
Судип Бхандари
1
@SudipBhandari Я задумался о том же самом, наконец, наткнулся на полезную статью в Википедии по этой теме: первоклассный гражданин / объект . Я нашел особенно полезным определение Робина Попплстоуна. (Между прочим, публикация статьи в WP может показаться супер очевидной, но я не понимал, что это фундаментальная концепция языка программирования)
mblakesley
21

«Когда кто-то говорит, что« все является объектом »(как в Python), действительно ли он имеет в виду, что« все первоклассно »?»

Да.

Все в Python - правильный объект. Даже вещи, которые являются «примитивными типами» в других языках.

Вы обнаружите, что такой объект, как на 2самом деле, имеет довольно богатый и сложный интерфейс.

>>> dir(2)
['__abs__', '__add__', '__and__', '__class__', '__cmp__', '__coerce__', '__delattr__', '__div__', '__divmod__', '__doc__', '__float__', '__floordiv__', '__getattribute__', '__getnewargs__', '__hash__', '__hex__', '__index__', '__init__', '__int__', '__invert__', '__long__', '__lshift__', '__mod__', '__mul__', '__neg__', '__new__', '__nonzero__', '__oct__', '__or__', '__pos__', '__pow__', '__radd__', '__rand__', '__rdiv__', '__rdivmod__', '__reduce__', '__reduce_ex__', '__repr__', '__rfloordiv__', '__rlshift__', '__rmod__', '__rmul__', '__ror__', '__rpow__', '__rrshift__', '__rshift__', '__rsub__', '__rtruediv__', '__rxor__', '__setattr__', '__str__', '__sub__', '__truediv__', '__xor__']

Поскольку в Python все является первоклассным объектом, неясных особых случаев относительно мало.

В Java, например, есть примитивные типы (int, bool, double, char), которые не являются правильными объектами. Вот почему Java должна представить Integer, Boolean, Double и Character в качестве типов первого класса. Этому может быть сложно научить новичков - не очевидно, почему и примитивный тип, и класс должны существовать бок о бок.

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

Тип 2- это type 'int'объект, у которого есть методы, атрибуты и тип.

>>> type(2)
<class 'int'>

Тип встроенного типа int- это type 'type'объект. У этого также есть методы и атрибуты.

>>> type(type(2))
<class 'type'>
С.Лотт
источник
1
Это верно для современного Python. В старом Python (версия 1? Это было до меня) вы не могли наследовать от int. Таким образом, «старые» классы против «нового стиля» (а в 3 больше нет классов старого стиля).
Кейт Пинсон,
17

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

Это самоочевидно для объектов, но не всегда так очевидно для функций или даже классов:

void f(int n) { return n * 2; }

void g(Action<int> a, int n) { return a(n); }

// Now call g and pass f:

g(f, 10); // = 20

Это пример на C #, где функции на самом деле не являются объектами первого класса. Поэтому в приведенном выше коде используется небольшой обходной путь (а именно вызываемый универсальный делегат Action<>) для передачи функции в качестве аргумента. Другие языки, такие как Ruby, позволяют обрабатывать даже классы и блоки кода как обычные переменные (или, в случае Ruby, константы).

Конрад Рудольф
источник
17

Из слайда в лекции « Структура и интерпретация компьютерных программ» (1986 г.), в которой, в свою очередь, цитируется Кристофер Стрейси :

Права и привилегии первоклассных граждан:

  • Называться переменными.
  • Для передачи в качестве аргументов процедурам.
  • Возвращаться как значения процедур.
  • Для включения в структуры данных
Федерико А. Рампони
источник
1

ИМО, это одна из тех метафор, которые используются для описания вещей на естественном языке. Этот термин в основном используется в контексте описания функций как объектов первого класса.

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

Первый класс здесь по существу означает, что он не обрабатывается как второй класс (с ухудшенным поведением). По сути, насмешка идеальна или неотличима.

Questzen
источник