Câu trả lời:
Định nghĩa
Một đối tượng là hạng nhất khi nó:
- có thể được lưu trữ trong các biến và cấu trúc dữ liệu
- có thể được truyền dưới dạng tham số cho chương trình con
- có thể được trả về như là kết quả của chương trình con
- có thể được xây dựng trong thời gian chạy
- có bản sắc nội tại (độc lập với bất kỳ tên nào)
Thuật ngữ "đối tượng" được sử dụng một cách lỏng lẻo ở đây, không nhất thiết phải nói đến các đối tượng trong lập trình hướng đối tượng. Các kiểu dữ liệu vô hướng đơn giản nhất, chẳng hạn như số nguyên và số dấu phẩy động, gần như luôn luôn là hạng nhất.
Khái niệm "công dân hạng nhất" hay "yếu tố hạng nhất" trong ngôn ngữ lập trình được giới thiệu bởi nhà khoa học máy tính người Anh Christopher Strachey vào những năm 1960 trong bối cảnh các chức năng hạng nhất. Công thức nổi tiếng nhất của nguyên tắc này có lẽ là trong Cấu trúc và diễn giải các chương trình máy tính của Gerald Jay Sussman và Harry Abelson:
- Chúng có thể được đặt tên theo các biến.
- Họ có thể được thông qua như là đối số để làm thủ tục.
- Họ có thể được trả lại như là kết quả của các thủ tục.
- Chúng có thể được bao gồm trong cấu trúc dữ liệu.
Về cơ bản, điều đó có nghĩa là bạn có thể làm với phần tử ngôn ngữ lập trình này mọi thứ bạn có thể làm với tất cả các phần tử khác trong ngôn ngữ lập trình.
Đó là tất cả về "quyền bình đẳng": bạn có thể thực hiện tất cả các điều trên, với, giả sử, số nguyên, vậy tại sao mọi thứ khác phải khác?
Định nghĩa ở trên là một chút hạn chế theo nghĩa là nó chỉ thực sự nói về khía cạnh của hạng nhất có liên quan đến việc là đối tượng của chương trình. Một định nghĩa chung hơn sẽ là một thứ là hạng nhất nếu bạn có thể làm mọi thứ với nó, bạn cũng có thể làm với những thứ khác cùng loại.
Ví dụ, các toán tử Java và các phương thức Java có cùng loại. Bạn có thể định nghĩa các phương thức mới, bạn có thể (phần nào) tự do chọn tên các phương thức của riêng bạn, bạn có thể ghi đè các phương thức, bạn có thể quá tải các phương thức. James Gosling cũng có thể làm tất cả điều đó với các nhà khai thác, nhưng bạn và tôi không thể. Ý tôi là, trái với niềm tin phổ biến, Java làm nhà điều hành hỗ trợ quá tải: ví dụ, các +
nhà khai thác quá tải cho byte
, short
, int
, long
, float
, double
và String
, và IIRC trong Java 7 cũng cho BigInteger
và BigDecimal
(và có thể là một cặp vợ chồng tôi quên), nó chỉ là bạnkhông có bất kỳ ảnh hưởng nào đối với nó. Điều đó rõ ràng làm cho các nhà khai thác hạng hai theo định nghĩa thứ hai này. Lưu ý rằng các phương thức vẫn không có đối tượng hạng nhất theo định nghĩa đầu tiên, mặc dù. (Điều đó có làm cho các nhà khai thác hạng ba không?)
Thông thường, điều này đề cập đến một cấu trúc có thể vượt qua như một tham số, có thể được định nghĩa là một kiểu trả về từ một hàm hoặc có thể được gán một giá trị. Thông thường bạn cần có khả năng xây dựng chúng trong thời gian chạy. Ví dụ, một thể hiện của một lớp sẽ là một công dân hạng nhất trong c ++ hoặc java, nhưng một hàm trong C thì không.
Tôi muốn nói một tính năng là một công dân hạng nhất nếu nó được thực hiện chỉ bằng ngôn ngữ.
tức là nó không yêu cầu nhiều tính năng ngôn ngữ hoặc thư viện chuẩn để thực hiện tính năng đó.
Thí dụ:
Trong C / C ++, tôi không coi các chức năng là một công dân hạng nhất (những người khác có thể).
Điều này là do có nhiều cách để thao tác các chức năng được hỗ trợ trực tiếp bởi ngôn ngữ nhưng yêu cầu sử dụng các tính năng ngôn ngữ khác. Các tham số ràng buộc cho một chức năng không được hỗ trợ trực tiếp và bạn phải xây dựng một functor để thực hiện tính năng này.
Để thêm một ví dụ cho các câu trả lời đã được cung cấp:
Trong WCF / C #, bạn hiện phải đánh dấu một đối tượng lớp bằng thuộc tính hợp đồng dịch vụ để nó hoạt động như một dịch vụ. Không có những thứ như:
public **service** MyService (in relation public **class** MyClass).
Một lớp là một công dân hạng nhất trong c #, nơi không có dịch vụ.
Hi vọng điêu nay co ich