OOP đã phát triển như thế nào để bao gồm khái niệm Thuộc tính


11

Tôi đến từ nền tảng C ++ và đang tìm hiểu về C # trong công việc hiện tại của mình và tôi đã đọc rất nhiều câu hỏi và trả lời về sự khác biệt giữa các lĩnh vực và tài sản công cộng và tất cả các biến đổi qua lại trong các biến thể và hiện thân của điều này câu hỏi cơ bản (ví dụ bài SO này và tất cả các câu hỏi liên quan ). Tất cả những câu hỏi đó đều được giải quyết về sự khác biệt thực tế được coi là sự tồn tại của một hệ thống tài sản nhưng tôi nghĩ sẽ tốt khi tiếp cận chủ đề này theo những gì các nhà thiết kế của tất cả các ngôn ngữ quyết định hỗ trợ các thuộc tính trong lần đầu tiên nơi đã suy nghĩ (kiểm tra danh sách trong bài viết Wikipedia ở đây). Làm thế nào OOP phát triển từ C ++ / Java để mở rộng thành những gì bài viết Wikipedia xác định thú vị là một trung gian giữa các phương thức và dữ liệu thành viên:

"Nghĩa là, các thuộc tính là trung gian giữa mã thành viên (phương thức) và dữ liệu thành viên (biến thể hiện) của lớp và các thuộc tính cung cấp mức độ đóng gói cao hơn các trường công khai."

MSDN thêm nền tảng:

"Mặc dù các thuộc tính về mặt kỹ thuật rất giống với các phương thức, nhưng chúng khá khác nhau về các kịch bản sử dụng. Chúng nên được xem là các trường thông minh. Chúng có cú pháp gọi các trường và tính linh hoạt của các phương thức."

Tôi muốn biết làm thế nào mà nó đạt được ở mức độ đóng gói trung gian này tỏ ra hữu ích cho lập trình nói chung. Tôi cho rằng khái niệm này đã không xuất hiện ở lần đầu tiên xuất hiện các ngôn ngữ lập trình thể hiện mô hình OOP.


8
Tính năng ngôn ngữ trần chỉ là đường cú pháp thuận tiện cho các phương thức getter và setter. Cho dù có những lý do sâu xa hơn đằng sau việc giải thích và thuật ngữ, tôi không biết.

Trong một nhóm các chuyên gia OO, tiêu đề câu hỏi của bạn có thể gây kích động và có thể làm bạn mất tập trung vào những gì bạn đang hỏi. Không phải là tôi tự mình nuôi dưỡng một chuyên gia OO, tôi chỉ là một "người dùng OO" trong vài năm.
Doc Brown

Đó là một cú pháp cú pháp mà tôi đã bỏ lỡ khi chuyển từ 'phương thức không tham số' trong Python sang C ++. BMI = bob.weight/sq(bob.height)đọc đẹp hơn mà không cần ()IMO.
OJFord

Tôi nghĩ rằng các thuộc tính nằm trong Visual Basic (không phải .net) ban đầu, như một cách để định cấu hình đối tượng Active X (COM). Lưới tài sản trong công cụ này có thể có liên quan đến việc áp dụng các thuộc tính trong các ngôn ngữ. Lưu ý rằng Visual Basic ban đầu không được định hướng đối tượng theo nhiều cách, nhưng nó có khả năng tạo ra thứ gì đó giống như các lớp.
Frank Hileman

Tiếp tục: cửa sổ thuộc tính là một cách để cấu hình các đối tượng mà không cần viết mã. Nó được gọi là phát triển RAD. Liên kết này chứa một ảnh chụp màn hình của cửa sổ thuộc tính VB6: microsoft.com/mspress/books/WW/sampchap/4068.aspx
Frank Hileman

Câu trả lời:


5

Đó là tất cả về Đóng gói và Nguyên tắc Truy cập Thống nhất.

Một đối tượng sẽ có thể trả lời tin nhắn bằng cách trả về dữ liệu hiện có hoặc chạy một phương thức, nhưng người gửi không thể biết đó là thông báo nào. Hoặc nếu bạn xem điều này từ phía người gửi: người gửi sẽ có thể truy cập dữ liệu hiện có hoặc chạy một phương thức thông qua giao diện thống nhất.

Có một số cách để đạt được điều này:

  • loại bỏ dữ liệu hoàn toàn, chỉ cần có phương thức (Drameak làm điều này)

    • một hình thức ít triệt để hơn ở trên: loại bỏ dữ liệu trong giao diện công cộng , nghĩa là làm cho dữ liệu luôn ở chế độ riêng tư, trong giao diện công cộng, chỉ hiển thị các phương thức (Smalltalk, Ruby làm điều này)
  • loại bỏ các phương thức hoàn toàn, chỉ cần có dữ liệu (Tự thực hiện điều này, "phương thức" chỉ là Methodcác đối tượng được gán cho các biến thể hiện, các biến thể hiện được tra cứu với công văn ảo)

  • không phân biệt cú pháp hoặc ngữ nghĩa giữa các phương thức và dữ liệu (Scala thực hiện điều này, việc truy cập một trường không thể phân biệt về mặt cú pháp với việc gọi một phương thức mà không có danh sách đối số ( foo.bar), việc gán cho một trường không thể phân biệt về mặt cú pháp với cách gọi một phương thức có tên đặc biệt ( foo.bar = baz) là giống nhau như foo.bar_=(baz)nghĩa là gọi một phương thức có tên foo_=và các giá trị chỉ đọc có thể được ghi đè hoặc được thực hiện bởi một phương thức không có danh sách tham số (tức là val foo) trong một siêu lớp có thể được ghi đè (hoặc abstract valđược thực hiện) trong một lớp con bằng một phương thức def foo)

Tuy nhiên, Java không tuân theo Nguyên tắc truy cập thống nhất. Trong Java, có thể phân biệt giữa truy cập dữ liệu và chạy một phương thức. foo.barkhác với foo.bar(). Lý do cho điều này là các trường và phương thức là khác biệt về mặt ngữ nghĩa và cú pháp.

C # cố gắng khắc phục điều này bằng cách thêm thuộc tính vào ngôn ngữ, về cơ bản là các phương thức trông giống như các trường. Tuy nhiên, các cuộc gọi phương thức vẫn nhìn và cảm nhận khác với truy cập trường và thuộc tính. Các trường và thuộc tính hiện có Quyền truy cập thống nhất, nhưng các phương thức vẫn không có.

Vì vậy, điều này không thực sự khắc phục vấn đề: bạn không thể sửa có hai cách khác nhau để truy cập mọi thứ bằng cách thêm cách thứ ba để truy cập mọi thứ! Ngay cả khi cách thứ ba đó trông giống như một trong hai cách khác, bạn vẫn sẽ có (ít nhất) hai cách khác nhau. Bạn chỉ có thể khắc phục bằng cách loại bỏ tất cả các cách khác nhau ngoại trừ một hoặc loại bỏ sự khác biệt.

Hoàn toàn ổn khi có một ngôn ngữ với các phương thức, thuộc tính và trường, nhưng cả ba nên có quyền truy cập thống nhất.


1
Tại sao bạn (và những người khác) nghĩ rằng việc duy trì Quyền truy cập thống nhất là rất quan trọng? Với một phương thức bạn có thể muốn cung cấp cho nó các tham số để thay đổi những gì nó làm hoặc hành động theo. Với một trường hoặc thuộc tính bạn không có khả năng này, bạn thường chỉ trả về dữ liệu (mặc dù một thuộc tính có thể được triển khai dưới dạng chạy phương thức thay vì chỉ hiển thị trường riêng). Điều đó có vẻ trực quan với tôi, có lẽ chỉ vì tôi đã quen với nó, nhưng bạn sẽ đạt được gì trong sự thanh lịch hoặc năng suất bằng cách thực thi truy cập thống nhất? Bạn có sợ bạn đang rò rỉ chi tiết thực hiện bên ngoài lớp học?
Mike hỗ trợ Monica

1
UAP là về bảo lưu quyền tự do thay đổi chi tiết triển khai mà không phá vỡ giao diện chung. Ví dụ thông thường là thêm đăng nhập. Nếu tôi cung cấp quyền truy cập thông qua một phương thức, tôi có thể thay đổi một cách tầm thường các phần bên trong của phương thức để ghi vào nhật ký. Với trường công khai, tôi không thể thêm ghi nhật ký mà không biến nó thành phương thức, điều này phá vỡ tất cả mã khách hàng. Nếu phá vỡ các thay đổi không thể bị rủi ro, sử dụng các phương pháp là bắt buộc. Các thuộc tính là sự thỏa hiệp tối ưu vì chúng là các phương thức đầy đủ nhưng trông giống như các trường. Tuân thủ UAP cải thiện việc đóng gói và giảm khớp nối chặt chẽ.
amon

Rất nhiều câu trả lời hay cho câu hỏi này nhưng tôi nghĩ rằng câu hỏi này đánh vào đầu bằng cách rút ra các khía cạnh cơ bản hơn của bản chất của ngôn ngữ lập trình và xây dựng về khái niệm chính thức có liên quan của UAP. Solid
jxramos

18

Chà, tôi không chắc chắn 100%, nhưng tôi đoán mọi thứ có lẽ đơn giản hơn bạn mong đợi. Từ các trường mô hình hóa OO của những năm 90, đã có nhu cầu về các lớp mô hình hóa với các thuộc tính thành viên được đóng gói và khi được triển khai bằng các ngôn ngữ như C ++ hoặc Java, điều này thường dẫn đến mã với rất nhiều getters và setters, vì vậy rất nhiều "tiếng ồn" mã cho một yêu cầu tương đối đơn giản. Lưu ý rằng hầu hết (có thể là tất cả, không kiểm tra điều này) các ngôn ngữ được liệt kê trong bài viết Wikipedia được liên kết của bạn bắt đầu giới thiệu "thuộc tính" của các đối tượng vào cuối những năm 90 trở đi.

Tôi đoán đó là lý do chính khiến các nhà thiết kế ngôn ngữ quyết định thêm một số đường cú pháp để giảm tiếng ồn đó. Và mặc dù tài sản này chắc chắn không có "cốt lõi OO khái niệm", họ ít nhất có một cái gì đó để làm với định hướng đối tượng. Chúng không hiển thị "một sự tiến hóa của OOP" (như tiêu đề câu hỏi của bạn giả định), nhưng chúng hỗ trợ mô hình OO ở cấp ngôn ngữ lập trình để giúp việc triển khai dễ dàng hơn.


Nó không liên quan gì đến lập trình hướng đối tượng, ngoại trừ theo nghĩa một thuộc tính là sự trừu tượng của một trường và các trường là một phần của lập trình hướng đối tượng. Nhưng các thuộc tính không cần thiết cho lập trình hướng đối tượng, như bạn lưu ý chính xác.
Frank Hileman

2
@FrankHileman: "một tài sản là một khái niệm trừu tượng của một trường, và các lĩnh vực là một phần của chương trình hướng đối tượng" - tốt, mà âm thanh với tôi như bạn đồng ý với khái niệm thực sự ít nhất một cái gì đó để làm với OOP. Và đó là lý do tại sao bạn đánh giá thấp tôi?
Doc Brown

3
cười lớn. Bạn có thể đổ lỗi cho anh ấy? Anh tuột ra khỏi nhà vệ sinh và đập đầu vào bồn rửa. Dù sao đi nữa ... Cách mà tôi luôn thấy đó là các thuộc tính không hoàn toàn thuộc về OO. Họ giúp đóng gói và đóng gói giúp với OO.
MetaFight

1
Hà! Đây là phần giới thiệu về lập trình viên.stackexchange cho tôi. Lol, nóng hơn rất nhiều so với trải nghiệm tương đương của tôi trong dòng stackover ol đơn giản :-p Cách tốt để trộn lẫn trong ngày!
jxramos


11

Bạn có nó ngược (loại). Lambda Compus tồn tại gần như là cơ sở chính thức cốt lõi cho các ngôn ngữ lập trình, và đã có trong nhiều thập kỷ. Nó không có lĩnh vực.

Để mô hình hóa trạng thái có thể thay đổi, bạn cần thực hiện hai khái niệm trừu tượng. Một đại diện cho việc thiết lập một số trạng thái và một trạng thái khác lấy trạng thái đó (Chương 13 trong phiên bản TaPL của tôi để tham khảo). Nghe có vẻ quen? Từ nền tảng lý thuyết , OO đã không tiến hóa để có thứ này. OO đọc Ngôn ngữ lập trình 101 và thực hiện một bước tiến.

Từ góc độ thực tế , có hai động lực khá rõ ràng. Bạn đến từ nền C ++, vì vậy điều gì sẽ xảy ra nếu bạn có trường công khai - giả sử ... văn bản trong hộp văn bản. Điều gì xảy ra khi bạn muốn thay đổi thiết kế của mình để "bất cứ khi nào hộp văn bản này thay đổi, hãy làm"? Bạn có thể giết trường đó, tạo một hoặc hai hàm và kết nối logic đó, vì bạn không thể tin tưởng các nhà phát triển tự gọi "UpdateTextbox". Đây là một thay đổi rất lớn đối với api của bạn (và thật không may vẫn là một thay đổi đột phá trong việc triển khai các thuộc tính của .NET). Loại hành vi này xuất hiện khắp nơi trong API Windows. Vì đó là một vấn đề lớn tại Microsoft, C # có thể muốn làm cho điều đó bớt đau đớn hơn.

Động lực lớn khác là Đậu Java và họ hàng của họ. Một số khung công tác đã được xây dựng để sử dụng phản chiếu Java để tìm kiếm GetXSetXghép nối và đối xử hiệu quả với chúng như các thuộc tính hiện đại. Nhưng vì chúng không phải là cấu trúc ngôn ngữ thực tế, nên các khung này rất mong manh và khó hiểu. Nếu bạn đánh máy tên, mọi thứ sẽ im lặng. Nếu một người được tái cấu trúc, không có gì chuyển sang phía bên kia của tài sản. Và thực hiện tất cả các trường mẫu / get / set soạn sẵn là dài dòng và tẻ nhạt (ngay cả đối với Java!). Vì C # được phát triển phần lớn là "Java với những bài học kinh nghiệm" nên nỗi đau là một trong những bài học đó.

Nhưng điều lớn nhất là khái niệm tài sản đã thành công. Thật dễ hiểu, thật dễ sử dụng. Chúng giúp áp dụng rất nhiều và như một công cụ , các lập trình viên đã phát hiện ra rằng các thuộc tính giải quyết một tập hợp con các vấn đề sạch hơn các hàm hoặc các trường.


7
Tôi đánh giá thấp bạn chủ yếu là vì tham khảo quá nhiều đến tào lao chính thức không liên quan. Việc triển khai thực tế các ngôn ngữ lập trình có nhiều điều nghiêm trọng hơn để xem xét so với việc liệu mô hình của chúng có được đưa vào phép tính lambda hay không.
DeadMG

9
@DeadMG - điều đó chắc chắn là đúng, nhưng mặt khác, những người thực hiện ngôn ngữ lập trình luôn luôn quen thuộc với những thứ nhảm nhí chính thức không liên quan đó . Nghĩ rằng nó không ảnh hưởng đến thiết kế của họ là ngây thơ.
Telastyn

3
Điều này chắc chắn không phải là "tào lao chính thức không liên quan." Tuy nhiên, tính toán lambda có thể không được xem xét nhiều cho các ngôn ngữ lập trình sớm. Nếu vậy, CPU có lẽ sẽ được định hướng nhiều hơn về tâm lý đó.
Frank Hileman

3
@FrankHileman - Tôi khá chắc chắn Lisp đã xem xét nó ...
Telastyn

4
@Telastyn - có - và Lisp ban đầu không phải là ngôn ngữ lập trình, nhớ chứ?
Frank Hileman

3

Trong .net cụ thể, các thuộc tính bắt nguồn từ những ngày Visual Basic cũ mà khi nó xảy ra không phải là đối tượng được định hướng theo cách chúng ta nghĩ về nó ngày nay. Nó chủ yếu được xây dựng xung quanh hệ thống COM mới sau đó xử lý bề ngoài mọi thứ không nhất thiết phải là các lớp mà về mặt các thành phần sẽ phơi bày các thuộc tính có thể được truy cập cả trong mã mà cả trong các trình soạn thảo đồ họa. Khi VB và C # mới được tạo được sáp nhập vào .net, VB đã thu được rất nhiều tính năng OOP và chúng giữ các thuộc tính kể từ khi xóa chúng sẽ giống như một bước lùi - hãy tưởng tượng nếu công cụ cập nhật mã tự động mà chúng có trong Visual Studio thay thế tất cả các thuộc tính của bạn bằng getters và setters và đã phá vỡ tính tương thích với tất cả các thư viện COM. Nó sẽ chỉ hợp lý để hỗ trợ họ trong tất cả.


Tôi không nghĩ bạn nên bỏ qua tổ tiên của C # xuất phát từ Delphi và từ trước đó, Object Pascal và Turbo Pascal với Object. Đây là hướng đối tượng và đã có các thuộc tính (mặc dù tôi không thể nhớ cho dù OP có tính chất từ TP5.5 hoặc cho dù họ đã được thêm vào;. Có lẽ họ đã tiếp tục vào C # bởi Anders bởi vì họ đã thực dụng một ý tưởng tốt
amaca

Rất thú vị khi bạn tình cờ là người duy nhất đánh vào khía cạnh thành phần của câu hỏi này. Tôi vừa thêm một nhận xét cho câu hỏi của mình liên kết đến một trang web liệt kê các thuộc tính như một phần của mô hình sự kiện phương thức thuộc tính mà C # thỏa mãn. Sau đó, tôi đã tìm kiếm trang câu hỏi của mình một lần nữa để tìm "thành phần" một vài thông tin sai nhưng câu trả lời của bạn tôi nghĩ thực sự trùng lặp với những gì tôi liên kết đến.
jxramos

3

Các thuộc tính không liên quan gì đến lập trình hướng đối tượng, vì các thuộc tính chỉ là đường cú pháp. Các thuộc tính trông giống như các trường trên bề mặt và trong thế giới .net, chúng được khuyến nghị rằng chúng hoạt động giống như các trường theo một số cách, nhưng chúng không phải là các trường theo bất kỳ ý nghĩa nào. Các thuộc tính là đường cú pháp cho một hoặc hai phương thức: một để lấy giá trị và một để đặt giá trị. Phương thức set hoặc phương thức get có thể được bỏ qua, nhưng không phải cả hai. Có thể không có trường lưu trữ giá trị được trả về bởi phương thức get. Bởi vì họ chia sẻ một cú pháp với các trường và vì họ thường sử dụng các trường, mọi người liên kết các thuộc tính với các trường.

Thuộc tính có lợi thế trên các lĩnh vực:

  • Trong phương thức tập thuộc tính, trước khi giá trị thuộc tính được lưu trữ, giá trị mới hoặc trạng thái của đối tượng, có thể được kiểm tra đối với tập hợp các điều kiện tiên quyết hoặc bất biến.
  • Một phương thức get property có thể tồn tại để thuận tiện, nếu việc truy xuất giá trị thuộc tính có thể được xem xét một cách hợp lý tương đương với việc truy xuất giá trị trường.
  • Phương thức tập thuộc tính có thể thực hiện các hoạt động khác, chẳng hạn như thông báo cho đối tượng cha hoặc đối tượng lắng nghe về sự thay đổi thành giá trị thuộc tính.

Vì các thuộc tính là sự trừu tượng của các trường và để thuận tiện cho cú pháp, các ngôn ngữ như C # đã sử dụng cú pháp trường cho các thuộc tính.


2
Dòng đầu tiên từ bài viết Wikipedia. "Một thuộc tính, trong một số ngôn ngữ lập trình hướng đối tượng, là một loại thành viên lớp đặc biệt ...". Vì vậy, câu đầu tiên của bạn là hoàn toàn sai. Và phần còn lại không trả lời câu hỏi.
Doc Brown

1
@DocBrown: Phản ứng thú vị. Nhiều bài viết Wikipedia rõ ràng không chính xác. Tôi giả sử bạn đang bảo vệ tác giả của bài viết cụ thể này?
Frank Hileman

1
Không phải tất cả các tính năng của ngôn ngữ lập trình hướng đối tượng đều liên quan đến các khái niệm hướng đối tượng.
Frank Hileman

1
Điều đó không thay đổi thực tế bạn không trả lời câu hỏi.
Doc Brown

3
Cần lưu ý rằng nó không chỉ là setter là tùy chọn. Bạn có thể có các thuộc tính chỉ setter.
Telastyn

2

Đó là một vấn đề thực hiện so với ngụ ý . Các thuộc tính nằm trong OOP trước khi C ++ hoặc Java xuất hiện (chúng ở đó, với một chút gồ ghề xung quanh các cạnh, trong Simula và chúng là nền tảng cho Smalltalk). Các thực thể có thuộc tính khác về mặt khái niệm với các giá trị được đính kèm theo mã. Các tiền tố get & set trong một số quy ước ngôn ngữ chỉ phục vụ cho việc làm vũng nước; chúng làm cho bạn biết về sự khác biệt giữa các trường và thuộc tính, giả sử rằng các trường có thể được truy cập trực tiếp mà không cần get / set theo cách thành ngữ với ngôn ngữ và điều đó bị rò rỉ.

Toàn bộ quan điểm của OOP là đối xử với mọi thứ như thể chúng là các thực thể trong thế giới "thực", không chỉ là các cấu trúc với một số mã được trộn lẫn. Một lập trình viên khác cần biết rất ít về cách tôi đã thực hiện mọi thứ, và hoàn toàn không nên quan tâm đến giá trị nào trong số các giá trị khác nhau mà chúng được phép nhận và / hoặc thiết lập là thực và ảo. Nếu bạn chạy qua một vectơ của tôi, bạn không cần phải biết liệu tôi đang lưu trữ góc và độ lớn hay các thành phần thực và ảo bên trong đối tượng vector. Nếu tôi thay đổi đại diện trong V2.0 của thư viện của mình, nó sẽ không ảnh hưởng đến mã của bạn (mặc dù bạn có thể muốn tận dụng các tính năng mới thú vị). Tương tự, có các thuộc tính mà một thực thể có thể có phụ thuộc vào dữ liệu bên ngoài thực thể, nhưng đó là những đặc tính chắc chắn từ quan điểm từ vựng. Bạn hỏi mọi người "bạn bao nhiêu tuổi", chứ không phải "vui lòng thực hiện phép tính sẽ tiết lộ tuổi của bạn cho tôi", mặc dù bạn biết rằng dữ liệu có sẵn cho "đối tượng" đó là ngày sinh (một thành viên bất biến riêng tư) và ngày nay ngày (một tài sản môi trường công cộng, tăng tự động, phụ thuộc vào múi giờ, thời gian tiết kiệm ánh sáng ban ngày và Dòng ngày quốc tế). Tuổi là một tài sản, không phải là một phương pháp, mặc dù phải mất một số tính toán để đến đó và không thể (ngoại trừ trong các biểu diễn máy tính đồ chơi của những thứ có tuổi thọ giới hạn giả tạo) được lưu trữ dưới dạng một trường. mặc dù bạn biết rằng dữ liệu có sẵn cho "đối tượng" đó là ngày sinh (thành viên không thay đổi tư nhân) và ngày hôm nay (một tài sản môi trường gia tăng tự động, phụ thuộc vào múi giờ, thời gian tiết kiệm ánh sáng ban ngày và Dòng ngày quốc tế ). Tuổi là một tài sản, không phải là một phương pháp, mặc dù phải mất một số tính toán để đến đó và không thể (ngoại trừ trong các biểu diễn máy tính đồ chơi của những thứ có tuổi thọ giới hạn giả tạo) được lưu trữ dưới dạng một trường. mặc dù bạn biết rằng dữ liệu có sẵn cho "đối tượng" đó là ngày sinh (thành viên không thay đổi tư nhân) và ngày hôm nay (một tài sản môi trường gia tăng tự động, phụ thuộc vào múi giờ, thời gian tiết kiệm ánh sáng ban ngày và Dòng ngày quốc tế ). Tuổi là một tài sản, không phải là một phương pháp, mặc dù phải mất một số tính toán để đến đó và không thể (ngoại trừ trong các biểu diễn máy tính đồ chơi của những thứ có tuổi thọ giới hạn giả tạo) được lưu trữ dưới dạng một trường.

Thay vì nghĩ về các thuộc tính như là đứa con hoang của các lĩnh vực và phương thức, nó thỏa mãn hơn nhiều đối với các phương thức như một loại tài sản chuyên biệt - những thứ mà thực thể của bạn có thể làm hơn là những thứ mà chúng là. Mặt khác, bạn không xử lý khái niệm với đối tượng / thực thể, bạn đang xử lý các bộ sưu tập dữ liệu tình cờ có mã được đính kèm với chúng. Việc triển khai có thể giống hệt nhau, nhưng ý nghĩa là khác nhau.

Tuy nhiên, không cần phải nói rằng sự trừu tượng này phải trả giá. Nếu một lập trình viên sử dụng một lớp không thể biết liệu anh ta hoặc cô ta đang truy cập dữ liệu khi nó được lưu trữ hay nhận / thiết lập các giá trị cần được tính toán, thì sẽ có một mức độ mà ngôn ngữ cũng không nhất thiết là không chắc chắn (và do đó có thể yêu cầu mọi thứ yêu cầu mã phải trung gian giữa các bộ truy cập / bộ chọn và giá trị). Không có gì sai về mặt khái niệm với "cấu trúc mã" - chúng chắc chắn có thể hiệu quả hơn nhiều - nhưng chúng rò rỉ việc triển khai ở khắp mọi nơi, và đó là một trong những điều mà OOP cần phải loại bỏ.


Tôi đồng ý với một số điểm và không đồng ý với người khác, nhưng thông điệp tổng thể là một trong những tốt: Một số thông tin về một đối tượng cần phải được tính toán nhưng vẫn còn về mặt kỹ thuật thông tin mà hơn là một hành động có thể được thực hiện .
Pharap

0

Hoàn toàn không có gì. Thuộc tính và OOP không có gì để làm với nhau. Các thuộc tính không có gì khác hơn là cú pháp cú pháp cho các lệnh gọi hàm, và do đó có chính xác cùng một tệp đính kèm OOP mà hàm gọi là do- nghĩa là không có gì.

Wikipedia là hoàn toàn không chính xác. Mẫu getMember / setMember mà bạn thấy trong Java cung cấp chính xác các ưu điểm (và nhược điểm) giống như các thuộc tính trong C #. Và bạn có thể sao chép mô hình này ngay cả trong C nếu bạn muốn.

Các thuộc tính trong C # không có gì khác ngoài cú pháp cú pháp được hỗ trợ bằng ngôn ngữ.


3
Bạn đã bao giờ thấy khái niệm thuộc tính trong bất kỳ ngôn ngữ lập trình nào bên ngoài một lớp hoặc bối cảnh đối tượng chưa? Tôi không có.
Doc Brown

1
@DocBrown: Tôi đã thực hiện nó. Thực tế là, các thuộc tính là các mục tiêu có giá trị khá thấp cho các tác giả ngôn ngữ, vì sự cải thiện của chúng so với các lệnh gọi hàm thông thường là thấp.
DeadMG

1
OP đang hỏi về lịch sử của các thuộc tính như là một khái niệm trong các ngôn ngữ lập trình phổ biến. Và trên thực tế, theo nghĩa lịch sử, có một mối liên hệ giữa các thuộc tính và OOP.
Doc Brown

2
Có lẽ tôi đã hơi vội vàng khi gán khái niệm thuộc tính này cho mô hình OOP mỗi se, nhưng như một khái niệm, nó chắc chắn vượt qua các ngôn ngữ riêng lẻ và các tính năng của chúng. Có lẽ tôi đang vật lộn để nói rõ bản thể luận thích hợp giữa hai người. Tôi không gợi ý qua tiêu đề của câu hỏi rằng các thuộc tính là một tính năng / khái niệm cơ bản của OOP tạo ra hoặc phá vỡ hình thức OOP, và tôi cảm thấy chúng chỉ có một thực tế trong không gian OOP này, đó là lý do tại sao tôi đặt câu hỏi như vậy .
jxramos

4
Chúng không chỉ là cú pháp đường trong C #, chúng tồn tại trong siêu dữ liệu lắp ráp dưới dạng các thành viên riêng biệt và bạn có thể thực hiện mọi việc với các thuộc tính bạn không thể với các trường, chẳng hạn như cơ sở dữ liệu.
Andy
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.