Ở đâu, trong một hệ thống hướng đối tượng, bạn nên chọn cấu trúc (kiểu C) trên các lớp?


9

C và rất có thể nhiều ngôn ngữ khác cung cấp một structtừ khóa để tạo cấu trúc (hoặc một cái gì đó theo cách tương tự). Đây là (ít nhất là trong C), từ quan điểm đơn giản hóa như các lớp, nhưng không có tính đa hình, kế thừa, phương thức, v.v.

Hãy nghĩ về một ngôn ngữ hướng đối tượng (hoặc đa mô hình) với các cấu trúc kiểu C. Bạn sẽ chọn chúng ở đâu trên các lớp học? Bây giờ, tôi không tin rằng chúng sẽ được sử dụng với OOP vì các lớp dường như thay thế mục đích của chúng, nhưng tôi tự hỏi liệu có những tình huống nào chúng có thể được ưa thích hơn các lớp trong các chương trình hướng đối tượng và trong tình huống nào. Có những tình huống như vậy?


Bạn đang sử dụng ngôn ngữ nào Bạn đang xuất bản cái gì? Hầu hết các ngôn ngữ OO hiện đại, ngoại trừ Java, đều hỗ trợ các thuộc tính theo cách này hay cách khác.
kevin cline

Câu trả lời:


16

Có một sự khác biệt mà tôi đã thấy trong một số cuốn sách giữa các đối tượng mang trạng thái và các đối tượng cung cấp chức năng. Các điều khoản chính xác khác nhau từ nguồn này đến nguồn khác. Nhưng nói chung, trước đây được phân biệt bằng cách có một loạt các trường và một loạt các cặp getters-setters đơn giản (và có thể là một nhà xây dựng).

Chúng đặc biệt phổ biến trong Java, đối với các lớp được đánh dấu rõ ràng là "tuần tự hóa".

Tôi sẽ lập luận rằng loại lớp này có ý nghĩa nhất là các cấu trúc, nếu bạn cảm thấy rằng không cần phải trực tiếp ẩn các thành viên (ví dụ, trong trường hợp các loại lồng nhau).


1
Robert C Martin gọi chúng là "đối tượng truyền dữ liệu" trong Clean Code .
dùng16764

5

Trong C, không có lớp, nên structcách để bó dữ liệu. Trong C ++, structcũng giống như classngoại trừ việc kế thừa và quyền truy cập thành viên publictheo mặc định chứ không phải private. C # cũng có một loại struct, nhưng tôi không biết đủ C # để nhận xét về nó. Lisp thông thường có defstructdạng, hoạt động giống như C struct, có thể, xem xét sự khác biệt về ngôn ngữ và nó khác với lớp Hệ thống đối tượng Lisp chung.

Tuy nhiên, có một sự khác biệt về khái niệm giữa một bó dữ liệu liên quan và một lớp thực và trong C ++ structthường được sử dụng cho một bó dữ liệu, trong khi classđược sử dụng cho các đối tượng được cho là có hành vi riêng. Theo hướng dẫn, tôi muốn nói rằng một classđại diện cho thứ gì đó bạn có thể nói điều gì đó hữu ích, chẳng hạn như bất biến lớp, trong khi đó structsẽ được kết hợp lỏng lẻo hơn với các giá trị dữ liệu không thực sự phụ thuộc nhiều vào các giá trị khác.


6
Sự khác biệt giữa a structvà a classcó ý nghĩa hơn trong C # - điều quan trọng là a structlà loại giá trị và a classlà loại tham chiếu. Microsoft khuyến cáo không sử dụng structnếu nội dung sẽ lớn hơn 16 byte hoặc hơn.
Carson63000

0

Ở mức độ rất cơ bản, sự khác biệt giữa một cấu trúc và một lớp dữ liệu thuần túy (một lớp không có chức năng nào ngoài các bộ truy cập thuộc tính)?

Không có gì ngoài dấu chân bộ nhớ thực sự.


0

Câu trả lời được chấp nhận là tốt. Tôi chỉ muốn thêm ....

Đôi khi, tốt hơn là đặt một phương thức trong một lớp. Mặt khác, tốt hơn là có một hàm bên ngoài trong đó struct / class được truyền vào dưới dạng tham số (ngay cả khi bạn đang thực hiện kiểu OOP).

ví dụ về thời điểm đặt một phương thức bên trong lớp: Hình chữ nhật.CaclulationArea ()

ví dụ về thời điểm đặt một hàm bên ngoài lớp: Canvas.Draw (Chỉnh hình chữ nhật)

bạn có thể đặt Draw () bên trong Hình chữ nhật và nó sẽ hoạt động. Nhưng vẽ là một hoạt động phụ thuộc tầng. Bạn sẽ không vẽ ở phía máy chủ, nhưng ở phía máy khách. Draw () sẽ không có ý nghĩa thậm chí tồn tại trên máy chủ. Tuy nhiên "CompateArea ()" độc lập với tier và là một thuộc tính thực sự của hình chữ nhật, vì vậy tốt hơn là đưa nó làm phương thức thành viên.


0

Đối với tôi, sự khác biệt lớn là liệu có bất biến giai cấp hay không.

Hay nói cách khác: tôi có thể tự do thay đổi bất kỳ trường nào thành bất kỳ giá trị nào tại bất kỳ thời điểm nào không? Nếu vậy, nó là một cấu trúc; Nếu không, đó là một lớp học.

Ví dụ thông thường của một cấu trúc là một điểm 2D, chỉ với một thành viên X và Y, có thể có bất kỳ giá trị nào và hoàn toàn độc lập với nhau. Truy cập công cộng là chấp nhận được.

Một ví dụ về một lớp là sự kết hợp của một con trỏ với một mảng ký tự và trường độ dài: độ dài phụ thuộc vào giá trị của con trỏ, và do đó nó không nên là một cấu trúc. Các trường nên ở chế độ riêng tư và truy cập phải đi qua setters và getters để đảm bảo lớp bất biến.


0

1) Mạng structs: các cấu trúc được truyền qua dây.

Nói chung và chính thức hơn, bất kỳ lớp nào bạn yêu cầu là POD, tầm thường, bố cục tiêu chuẩn hoặc một khái niệm liên quan. Để có một cuộc thảo luận tuyệt vời về các khái niệm này, với các ví dụ, hãy xem câu trả lời này (nó dành cho C ++ 11).

2) Functor (đặc biệt là vị ngữ), mà bạn sẽ chuyển qua các hàm như std::remove_if. Mặt khác, các lớp tương tự / kế thừa từ std::binary_functionhoặc tương tự.

3) Các khái niệm lập trình meta, có thể chỉ chứa constexprs công khai và / hoặc typedefs.

Chỉnh sửa: Lưu ý: Câu trả lời này áp dụng cho các lớp C ++ so với cấu trúc.

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.