Co to są obiekty „pierwszej klasy”?

191

Kiedy obiekty lub coś innego mówi się o „pierwszej klasie” w danym języku programowania i dlaczego? Czym różnią się od języków, w których nie są?

EDYTOWAĆ. Kiedy ktoś mówi „wszystko jest przedmiotem” (jak w Pythonie), czy rzeczywiście ma na myśli, że „wszystko jest najwyższej klasy”?

Federico A. Ramponi
źródło
1
Czy można migrować to pytanie do programmers.SE? Czy też byłoby to niewłaściwe? Myślę, że to pytanie jest dobre. Po prostu nie jestem w stanie powiedzieć, które forum najlepiej do niego pasuje.
Shashank Sawant
16
Wziął do ponownego ... niestety to naprawdę wydaje się, że został zamknięty przez ludzi, którzy nie programu, to wyraźnie na temat: /
djechlin

Odpowiedzi:

176

Krótko mówiąc, oznacza to, że nie ma żadnych ograniczeń dotyczących używania obiektu. Jest taki sam jak każdy inny obiekt.

Obiektem pierwszej klasy jest obiekt, który można dynamicznie tworzyć, niszczyć, przekazywać do funkcji, zwracać jako wartość i mieć wszystkie prawa, jakie mają inne zmienne w języku programowania.

W zależności od języka może to oznaczać:

  • wyrażanie się jako anonimowa wartość dosłowna
  • przechowywanie w zmiennych
  • przechowywanie w strukturach danych
  • posiadający wewnętrzną tożsamość (niezależnie od imienia)
  • porównywalne pod względem równości z innymi podmiotami
  • bycie możliwym do przejścia jako parametr do procedury / funkcji
  • podlegające zwrotowi w wyniku procedury / funkcji
  • możliwość tworzenia w czasie wykonywania
  • być do druku
  • być czytelnym
  • przenoszone między rozproszonymi procesami
  • przechowywanie poza uruchomionymi procesami

Źródło .

W funkcjach C ++ same nie są obiektami pierwszej klasy, jednak:

  • Możesz zastąpić operator „()”, dzięki czemu można mieć funkcję obiektu, która jest pierwszej klasy.
  • Wskaźniki funkcji są pierwszej klasy.
  • boost bind, lambda i funkcja oferują funkcje pierwszej klasy

W C ++ klasy nie są obiektami pierwszej klasy, ale instancjami tych klas są. W Pythonie zarówno klasy, jak i obiekty są obiektami pierwszej klasy. (Zobacz tę odpowiedź, aby uzyskać więcej informacji na temat klas jako obiektów).

Oto przykład funkcji pierwszej klasy 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

Źródło .

Elementy, które nie są obiektami pierwszej klasy, są nazywane obiektami drugiej klasy. Funkcje w C ++ są drugiej klasy, ponieważ nie można ich dynamicznie tworzyć.

Jeśli chodzi o edycję:

EDYTOWAĆ. Kiedy ktoś mówi „wszystko jest przedmiotem” (jak w Pythonie), czy rzeczywiście ma na myśli, że „wszystko jest najwyższej klasy”?

Termin obiekt może być używany luźno i nie oznacza bycia pierwszą klasą. I prawdopodobnie sensowniej byłoby nazwać całą koncepcję „bytami pierwszej klasy”. Ale w Pythonie starają się, aby wszystko było na najwyższym poziomie. Uważam, że intencja osoby, która złożyła twoje oświadczenie, oznaczała pierwszą klasę.

Brian R. Bondy
źródło
2
Czy możesz podać przykłady obiektów, które nie są „pierwszorzędne”?
Sudip Bhandari,
1
@SudipBhandari Zastanawiałem się nad tym samym, w końcu natknąłem się na pomocny artykuł Wikipedii na ten temat: obywatel / obiekt pierwszej klasy . Uważam, że definicja Robina Popplestone'a jest szczególnie pomocna. (Przy okazji, opublikowanie artykułu WP może wydawać się bardzo oczywiste, ale nie zdawałem sobie sprawy, że to podstawowa koncepcja języka programowania)
mblakesley
19

„Kiedy ktoś mówi„ wszystko jest przedmiotem ”(jak w Pythonie), czy rzeczywiście ma na myśli, że„ wszystko jest najwyższej klasy ”?

Tak.

Wszystko w Pythonie jest właściwym obiektem. Nawet rzeczy, które są „pierwotnymi typami” w innych językach.

Okazuje się, że taki obiekt 2ma w rzeczywistości dość bogaty i wyrafinowany interfejs.

>>> 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__']

Ponieważ w Pythonie wszystko jest pierwszorzędnym obiektem, jest stosunkowo mało niejasnych przypadków specjalnych.

Na przykład w Javie istnieją prymitywne typy (int, bool, double, char), które nie są właściwymi obiektami. Dlatego Java musi wprowadzić liczby całkowite, logiczne, podwójne i znakowe jako typy pierwszej klasy. To może być trudne do nauczenia dla początkujących - nie jest oczywiste, dlaczego zarówno prymitywny typ, jak i klasa muszą istnieć obok siebie.

Oznacza to również, że klasa obiektu jest - sama w sobie - obiektem. Różni się to od C ++, gdzie klasy nie zawsze mają wyraźne istnienie w czasie wykonywania.

Typem 2jest type 'int'obiekt, który ma metody, atrybuty i typ.

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

Typem typu wbudowanego intjest type 'type'obiekt. Ma to również metody i atrybuty.

>>> type(type(2))
<class 'type'>
S.Lott
źródło
1
Dotyczy to współczesnego Pythona. W starym Pythonie (wersja 1? To było przed moim czasem) nie można było dziedziczyć int. Zatem „stare” kontra „klasy nowego stylu” (a w 3 nie ma już klas starego stylu).
Keith Pinson
17

„Pierwsza klasa” oznacza, że ​​możesz operować nimi w zwykły sposób. W większości przypadków oznacza to po prostu, że możesz przekazać tym pierwszorzędnym obywatelom argumenty do funkcji lub zwrócić je z funkcji.

Jest to oczywiste dla obiektów, ale nie zawsze tak oczywiste dla funkcji, a nawet klas:

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

Jest to przykład w języku C #, w którym funkcje faktycznie nie są obiektami pierwszej klasy. Powyższy kod wykorzystuje zatem małe obejście (mianowicie ogólny delegat Action<>), aby przekazać funkcję jako argument. Inne języki, takie jak Ruby, pozwalają traktować nawet klasy i bloki kodu jako normalne zmienne (lub, w przypadku Ruby, stałe).

Konrad Rudolph
źródło
1

IMO to jedna z tych metafor używanych do opisu rzeczy w języku naturalnym. Termin ten jest zasadniczo używany w kontekście opisywania funkcji jako obiektów pierwszej klasy.

Jeśli weźmiesz pod uwagę język obiektowy, możemy nadać obiektom różne funkcje, takie jak: dziedziczenie, definicja klasy, możliwość przekazania do innych sekcji kodu (argumenty metody), możliwość przechowywania w strukturze danych itp. Jeśli możemy to zrobić tak samo z bytem, ​​który normalnie nie jest uważany za obiekt, podobnie jak funkcje w przypadku skryptu Java, takie byty są uważane za obiekty pierwszej klasy.

Pierwsza klasa zasadniczo tutaj oznacza, że ​​nie jest traktowana jak druga klasa (ze zdegradowanym zachowaniem). Zasadniczo kpiny są doskonałe lub nierozróżnialne.

questzen
źródło