Các đối tượng hạng nhất của thế giới là gì?


191

Khi nào các đối tượng hoặc một cái gì đó khác được gọi là "hạng nhất" trong một ngôn ngữ lập trình nhất định, và tại sao? Trong những gì họ khác với ngôn ngữ mà họ không phải là?

BIÊN TẬP. Khi một người nói "mọi thứ là một đối tượng" (như trong Python), anh ta thực sự có nghĩa là "mọi thứ đều là hạng nhất"?


1
Có thể chuyển câu hỏi này sang lập trình viên không? Hay nó cũng sẽ là một kẻ lạc loài? Tôi nghĩ rằng câu hỏi này là tốt. Chỉ không thể nói diễn đàn nào sẽ phù hợp nhất với nó.
Sawash Shashank

16
Được bình chọn để mở lại ... thật đáng buồn, điều này thực sự có vẻ như đã bị đóng cửa bởi những người không lập trình, nó rõ ràng về chủ đề: /
djechlin

Câu trả lời:


176

Nói tóm lại, điều đó có nghĩa là không có hạn chế nào đối với việc sử dụng đối tượng. Nó giống như mọi đối tượng khác.

Một đối tượng lớp đầu tiên là một thực thể có thể được tạo động, hủy, chuyển đến một hàm, được trả về dưới dạng một giá trị và có tất cả các quyền như các biến khác trong ngôn ngữ lập trình có.

Tùy thuộc vào ngôn ngữ, điều này có thể ngụ ý:

  • được thể hiện như một giá trị nghĩa đen
  • được lưu trữ trong các biến
  • được lưu trữ trong cấu trúc dữ liệu
  • có một bản sắc nội tại (độc lập với bất kỳ tên nào)
  • được so sánh cho bình đẳng với các thực thể khác
  • có thể vượt qua như một tham số cho một thủ tục / hàm
  • được trả về do kết quả của một thủ tục / hàm
  • có thể xây dựng trong thời gian chạy
  • có thể in được
  • có thể đọc được
  • được truyền giữa các quá trình phân tán
  • được lưu trữ bên ngoài các quy trình đang chạy

Nguồn .

Tuy nhiên, trong các hàm C ++ không phải là đối tượng hạng nhất:

  • Bạn có thể ghi đè toán tử '()' để có thể có hàm đối tượng, là lớp đầu tiên.
  • Con trỏ chức năng là lớp học đầu tiên.
  • tăng liên kết, lambda và chức năng cung cấp các chức năng hạng nhất

Trong C ++, các lớp không phải là đối tượng của lớp đầu tiên mà là các thể hiện của các lớp đó. Trong Python cả các lớp các đối tượng là các đối tượng lớp đầu tiên. (Xem câu trả lời này để biết thêm chi tiết về các lớp dưới dạng đối tượng).

Dưới đây là một ví dụ về các chức năng hạng nhất của 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

Nguồn .

Các thực thể không phải là đối tượng hạng nhất được gọi là đối tượng hạng hai. Các hàm trong C ++ là lớp thứ hai vì chúng không thể được tạo động.

Về chỉnh sửa:

BIÊN TẬP. Khi một người nói "mọi thứ là một đối tượng" (như trong Python), anh ta thực sự có nghĩa là "mọi thứ đều là hạng nhất"?

Thuật ngữ đối tượng có thể được sử dụng một cách lỏng lẻo và không có nghĩa là hạng nhất. Và nó có lẽ sẽ có ý nghĩa hơn để gọi toàn bộ khái niệm 'thực thể hạng nhất'. Nhưng trong Python họ có mục đích làm cho mọi thứ trở thành hạng nhất. Tôi tin rằng ý định của người đưa ra tuyên bố của bạn có nghĩa là hạng nhất.


2
Bạn có thể đưa ra một số ví dụ về các đối tượng không phải là 'hạng nhất' không?
Sudip Bhandari

1
@SudipBhandari Tôi tự hỏi điều tương tự, cuối cùng tình cờ thấy bài viết Wikipedia hữu ích về chủ đề này: công dân / đối tượng hạng nhất . Tôi thấy định nghĩa của Robin Popplestone đặc biệt hữu ích. (Btw, đăng một bài viết WP có vẻ rất rõ ràng nhưng tôi đã không nhận ra đây là một khái niệm ngôn ngữ lập trình cơ bản)
mblakesley

19

"Khi một người nói" mọi thứ là một đối tượng "(như trong Python), anh ta thực sự có nghĩa là" mọi thứ đều là hạng nhất "?"

Đúng.

Mọi thứ trong Python là một đối tượng thích hợp. Ngay cả những thứ là "loại nguyên thủy" trong các ngôn ngữ khác.

Bạn thấy rằng một đối tượng như 2thực sự có giao diện khá phong phú và tinh vi.

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

Bởi vì mọi thứ đều là đối tượng hạng nhất trong Python, nên có khá ít trường hợp đặc biệt tối nghĩa.

Ví dụ, trong Java, có các kiểu nguyên thủy (int, bool, double, char) không phải là đối tượng thích hợp. Đó là lý do tại sao Java phải giới thiệu Integer, Boolean, Double và Character như các loại hạng nhất. Điều này có thể khó dạy cho người mới bắt đầu - không rõ ràng tại sao cả loại nguyên thủy và lớp phải tồn tại song song.

Điều đó cũng có nghĩa là lớp của một đối tượng - chính nó - một đối tượng. Điều này khác với C ++, trong đó các lớp không phải luôn có sự tồn tại riêng biệt vào thời gian chạy.

Loại 2type 'int'đối tượng, có các phương thức, thuộc tính và một loại.

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

Loại của một kiểu tích hợp như inttype 'type'đối tượng. Điều này có phương thức và thuộc tính, cũng.

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

1
Điều này đúng với Python hiện đại. Trong Python cũ (phiên bản 1? Trước thời của tôi), bạn không thể kế thừa từ đó int. Do đó, "lớp cũ" so với "lớp kiểu mới" (và trong 3, không còn lớp kiểu cũ nữa).
Keith Pinson

17

Lớp đầu tiên có nghĩa là bạn có thể vận hành chúng theo cách thông thường. Hầu hết thời gian, điều này chỉ có nghĩa là bạn có thể chuyển những công dân hạng nhất này làm đối số cho các chức năng hoặc trả lại chúng từ các chức năng.

Điều này là hiển nhiên đối với các đối tượng nhưng không phải lúc nào cũng rõ ràng đối với các hàm hoặc thậm chí các lớp:

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

Đây là một ví dụ trong C # nơi các hàm thực sự không phải là đối tượng hạng nhất. Do đó, đoạn mã trên sử dụng một cách giải quyết nhỏ (cụ thể là một đại biểu chung được gọi Action<>) để truyền một hàm làm đối số. Các ngôn ngữ khác, chẳng hạn như Ruby, cho phép coi cả các lớp và khối mã là các biến thông thường (hoặc trong trường hợp của Ruby, các hằng số).



1

IMO đây là một trong những phép ẩn dụ được sử dụng để mô tả sự vật bằng ngôn ngữ tự nhiên. Thuật ngữ này về cơ bản được sử dụng trong ngữ cảnh mô tả các hàm như các đối tượng hạng nhất.

Nếu bạn xem xét một ngôn ngữ hướng đối tượng, chúng ta có thể truyền các tính năng khác nhau cho các đối tượng, ví dụ: kế thừa, định nghĩa lớp, khả năng chuyển sang các phần khác của mã (đối số phương thức), khả năng lưu trữ trong cấu trúc dữ liệu, v.v. Nếu chúng ta có thể làm cùng với một thực thể thường không được coi là một đối tượng, giống như các hàm trong trường hợp tập lệnh java, các thực thể đó được coi là các đối tượng hạng nhất.

Lớp thứ nhất về cơ bản ở đây có nghĩa là, không được xử lý như lớp thứ hai (với hành vi xuống cấp). Về cơ bản, sự chế giễu là hoàn hảo hoặc không thể phân biệt.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.