Tại sao không có định nghĩa nhất quán về các khái niệm thiết yếu đối với OOP?


12

Tôi rất mới với lập trình và hơi bối rối khi đọc \ nghe các quy ước khác nhau từ các nguồn khác nhau:

Liệu lập trình hướng đối tượng có 4 hoặc 5 khái niệm?

Là người mới, tôi hiểu đây là 5 khái niệm:

  • Trừu tượng
  • Di sản
  • Đóng gói
  • Đa hình
  • Tính mô đun

Vì vậy, tại sao tôi không tìm thấy một định nghĩa "nghiêm ngặt" hơn và dường như có một số sắp xếp của các khái niệm này ngoài kia?


7
Có thể vì nó không giống như toán học (một số khái niệm trong CS là vậy, nhưng tôi nghĩ OOP không thuộc về thể loại này), vì vậy không có định nghĩa chặt chẽ nào để bắt đầu. Vì vậy, ví dụ 'mô-đun' quan trọng như thế nào? Nó thực sự đặc biệt với OOP đến nỗi chúng ta phải đề cập đến nó hay nó sẽ chỉ là một cái gì đó xảy ra nếu nó áp dụng đúng bốn cái kia? Một số danh sách thêm 'hệ thống phân cấp', nhưng đây có thực sự là một cái gì đó thêm hoặc chỉ sau sự kế thừa và đa hình?
thorsten müller 10/03/2016

6
Lời khuyên: Là một lập trình viên rất mới, bạn không nên quá bận tâm đến việc hiểu thuật ngữ và lý thuyết. Thu thập một số kinh nghiệm lập trình thực hành trước tiên, và nó sẽ trở nên rõ ràng hơn nhiều những gì những người này đang nói về.
Philipp

9
Một điều nữa là OOP đang thay đổi theo thời gian. Rất nhiều sự tập trung trong những ngày đầu C ++ (tôi biết OOP quay trở lại xa hơn thế) là về Kế thừa và Đa hình. Ngày nay tập trung nhiều vào Trừu tượng và Đóng gói.
Bent

3
Một số thảo luận thú vị về sự thiếu chính xác trong định nghĩa của OO có thể được tìm thấy ở đây: c2.com/cgi/wiki?NobodyAgreesOnWhatOoIs
MichelHenrich

Câu trả lời:


27

Lý do bạn tìm thấy những giải thích khác nhau về ý nghĩa của lập trình hướng đối tượng là bởi vì không có một cá nhân hay tổ chức nào có thẩm quyền để đưa ra một định nghĩa áp dụng phổ biến nghiêm ngặt.

Lập trình hướng đối tượng không phải là tiêu chuẩn ISO hay luật khoa học. Đó là một triết lý. Và như với tất cả các triết lý, có tất cả các loại giải thích khác nhau và không có cách giải thích nào được áp dụng phổ biến. Khi bạn đọc một văn bản cho bạn biết những khái niệm bạn nên tuân theo khi thiết kế kiến ​​trúc phần mềm, bạn sẽ xem đây là một hướng dẫn dựa trên ý kiến ​​của tác giả hình thành trong kinh nghiệm chuyên môn của họ, chứ không phải là một sự thật phổ quát.


12

Liệu lập trình hướng đối tượng có 5 hoặc 4 thành phần?

Như những người khác đã đề cập, "OO" không thực sự có bất kỳ thành phần nào , bởi vì đó là cách suy nghĩ về mô hình hóa các giải pháp cho các vấn đề và không phải là bộ công cụ cũng như một tập hợp các quy trình được xác định rõ ràng.

Là người mới, tôi hiểu đây là 5 thành phần:

Trừu tượng, kế thừa, đóng gói, đa hình và mô đun?

Kế thừa và Đa hình là các tính năng ngôn ngữ lập trình. Thật tốt khi bạn hiểu những điều này, nhưng hãy nhớ rằng chúng là những công cụ (có nghĩa là, như với bất kỳ công cụ nào khác, chúng chỉ nên được sử dụng để giải quyết các vấn đề cụ thể và không được coi là mục tiêu hay thứ gì đó để phấn đấu). Bạn có thể (và thường nên) viết mã "OO" mà không cần sử dụng một trong hai. Một số mã "OO" tốt nhất mà tôi từng thấy sử dụng rất ít tính kế thừa hoặc đa hình.

Trừu tượng hóa, đóng gói và mô đun ít liên quan đến mã và nhiều hơn về cách bạn nhìn nhận vấn đề, cách bạn cố gắng hiểu vấn đề đó và cách bạn thiết kế và cấu trúc giải pháp của mình theo mã.

Ngoài ra, những ý tưởng thiết kế đó không dành riêng cho "OO". Rất có thể là bây giờ bạn có thể hiểu chúng ở mức cơ bản, có thể bao gồm khả năng giải thích một định nghĩa hoàn hảo trong sách giáo khoa, và áp dụng chúng cho các vấn đề hơi không cần thiết; mặc dù một bài kiểm tra sâu hơn về sự hiểu biết đang được đưa ra một vấn đề phức tạp rất lớn và mức độ phức tạp mà bạn có thể xử lý.

Một bài kiểm tra khác về sự hiểu biết là cách tiếp cận bạn sử dụng để phá vỡ một vấn đề; và những người mới tham gia "OO", những người thường được dạy về OO về mô hình hóa dữ liệu (bởi vì đó là cách mà hầu hết mọi người thường hiểu về nó trong những năm 1990), và thường kết thúc tập trung vào các khía cạnh sai của vấn đề - tức là họ tập trung quá nhiều vào dữ liệu và họ không tập trung đủ vào hành vi.

Ví dụ, ví dụ cổ điển thường đề cập đến các thực thể như Dog, Cat, Elephant, Seagull, Shark,, vv Người mới đến "OO" thường nhìn vào ví dụ như vậy và ngay lập tức nghĩ rằng "Ồ, tôi cần một tổ chức cơ sở gọi là Animal" , và họ thậm chí có thể kết thúc với khác các thực thể trung gian như MammalAmphibiantrong một gia tài thừa kế gọn gàng, với các thuộc tính khác nhau trong mỗi một.

Mặc dù cách suy nghĩ đó thể hiện sự hiểu biết rất cơ bản về một số khái niệm OO, một lập trình viên OO có kinh nghiệm sẽ không bao giờ tiếp cận nó như thế cũng như không đi đến kết luận đó (Và thực sự sẽ phàn nàn rằng họ không có đủ thông tin), bởi vì cách tiếp cận đó thể hiện Entity mô hình hóa chứ không phải mô hình hóa OO, và vì ví dụ giả định không nói gì về hành vi của những con vật đó (Và nhiều người sẽ tranh luận ngày nay rằng bản chất của OO là tất cả trong hành vi và chức năng).

Theo truyền thống, cách tìm hiểu về "OO" bao gồm dành thời gian xây dựng các tóm tắt sai khi bạn không biết gì (hoặc quá ít) về hành vi của vấn đề bạn đang mô hình hóa hoặc khi bạn mắc lỗi tập trung sự chú ý vào các thực thể thay vì chức năng, mặc dù một phần là bởi vì rất nhiều sách, khóa học và hướng dẫn trực tuyến được viết trong nhiều năm qua đã (hướng dẫn) người học đi theo con đường đó trong một thời gian dài (thủy triều đang thay đổi).

Nhìn chung, rất nhiều sự hiểu biết của bạn sẽ đi xuống để trải nghiệm. Những khái niệm bạn đã học cho đến nay là một khởi đầu tốt, có nhiều khái niệm bạn sẽ cần học trên đường đi (ví dụ: các nguyên tắc "RẮN" và "KHÔ"), và bạn sẽ cần phải mất một thời gian dài lý thuyết vào thực tiễn với các vấn đề rất phức tạp thực sự trước khi tất cả có khả năng "nhấp chuột" vào vị trí.


2
Một con cá mập và một con ếch đều bơi, nhưng một con là cá, con kia là động vật lưỡng cư. Tôi nghĩ rằng ví dụ đó mô tả quan điểm của bạn tốt.
RubberDuck

10

Thuật ngữ "Định hướng đối tượng" được đặt ra bởi Tiến sĩ Alan Kay, vì vậy ông là nguồn có thẩm quyền về ý nghĩa của nó, và ông định nghĩa nó như vậy :

OOP với tôi có nghĩa là chỉ nhắn tin, duy trì và bảo vệ cục bộ và che giấu quá trình nhà nước, và cực kỳ ràng buộc tất cả mọi thứ.

Hãy phá vỡ nó:

  • nhắn tin ("gửi phương thức ảo", nếu bạn không quen với Smalltalk)
  • quy trình nhà nước nên được
    • giữ lại tại địa phương
    • bảo vệ
    • ẩn
  • cực kỳ muộn của tất cả mọi thứ

Thực hiện khôn ngoan, tin nhắn là lời kêu gọi thủ tục cuối-bound, và nếu cuộc gọi thủ tục được cuối-bound, thì bạn không thể biết lúc thiết kế những gì bạn đang đi để gọi, vì vậy bạn không thể thực hiện bất kỳ giả định về đại diện cụ thể của nhà nước. Vì vậy, thực sự là về nhắn tin, ràng buộc muộn là việc thực hiện nhắn tin và đóng gói là hệ quả của nó.

Sau đó, ông đã làm rõ rằng " Ý tưởng lớn là" nhắn tin " ", và hối tiếc vì đã gọi nó là "hướng đối tượng" thay vì "hướng thông điệp", bởi vì thuật ngữ "hướng đối tượng" tập trung vào thứ không quan trọng (đối tượng ) và phân tâm từ những gì thực sự quan trọng (nhắn tin):

Chỉ cần một lời nhắc nhở nhẹ nhàng rằng tôi đã chịu một số đau đớn ở OOPSLA cuối cùng để cố gắng nhắc nhở mọi người rằng Smalltalk không chỉ KHÔNG phải là cú pháp của nó hay thư viện lớp, thậm chí nó không phải là về các lớp. Tôi xin lỗi vì từ lâu tôi đã đặt ra thuật ngữ "đối tượng" cho chủ đề này bởi vì nó khiến nhiều người tập trung vào ý tưởng ít hơn.

Ý tưởng lớn là "nhắn tin" - đó là tất cả những gì về hạt nhân của Smalltalk / Squeak (và đó là thứ chưa bao giờ hoàn thành trong giai đoạn Xerox PARC của chúng tôi). Người Nhật có một từ nhỏ - ma - cho "cái nằm ở giữa" - có lẽ tương đương với tiếng Anh gần nhất là "interstitial". Chìa khóa trong việc tạo ra các hệ thống tuyệt vời và có thể phát triển là nhiều hơn nữa để thiết kế cách các mô-đun giao tiếp thay vì các đặc tính và hành vi bên trong của chúng. Hãy nghĩ về internet - để sống, nó (a) phải cho phép nhiều loại ý tưởng và hiện thực khác nhau vượt quá mọi tiêu chuẩn duy nhất và (b) để cho phép mức độ tương tác an toàn khác nhau giữa các ý tưởng này.

(Tất nhiên, ngày nay, hầu hết mọi người thậm chí không tập trung vào các đối tượng mà vào các lớp học, điều này thậm chí còn sai hơn.)

Nhắn tin là nền tảng cho OO, cả dưới dạng ẩn dụ và như một cơ chế.

Nếu bạn gửi tin nhắn cho ai đó, bạn sẽ không biết họ làm gì với nó. Điều duy nhất bạn có thể quan sát, là phản ứng của họ. Bạn không biết liệu họ có tự xử lý tin nhắn hay không (tức là nếu đối tượng có phương thức), nếu họ chuyển tiếp tin nhắn cho người khác (ủy quyền / ủy quyền), nếu họ thậm chí hiểu nó. Đó là tất cả những gì đóng gói, đó là tất cả những gì về OO. Bạn thậm chí không thể phân biệt một proxy với thực tế, miễn là nó đáp ứng như bạn mong đợi.

Một thuật ngữ "hiện đại" hơn cho "nhắn tin" là "gửi phương thức động" hoặc "gọi phương thức ảo", nhưng điều đó làm mất đi phép ẩn dụ và tập trung vào cơ chế.

Vì vậy, có hai cách để xem xét định nghĩa của Alan Kay: nếu bạn nhìn vào nó đứng một mình, bạn có thể quan sát rằng nhắn tin về cơ bản là một cuộc gọi thủ tục muộn và ràng buộc muộn có nghĩa là đóng gói, vì vậy chúng tôi có thể kết luận rằng # 1 và # 2 thực sự là dư thừa, và OO là tất cả về ràng buộc muộn.

Tuy nhiên, sau đó ông đã làm rõ rằng điều quan trọng là nhắn tin, và vì vậy chúng ta có thể nhìn nó từ một góc độ khác: nhắn tin bị ràng buộc muộn. Bây giờ, nếu nhắn tin là điều duy nhất có thể, thì số 3 sẽ là sự thật một cách tầm thường: nếu chỉ có một điều, và điều đó bị ràng buộc muộn, thì tất cả mọi thứ đều bị ràng buộc muộn. Và một lần nữa, đóng gói theo sau từ tin nhắn.

Những điểm tương tự cũng được thực hiện trong Tìm hiểu về trừu tượng dữ liệu, được xem xét lại bởi William R. Cook và cũng là Đề xuất của ông về các định nghĩa hiện đại, đơn giản về "Đối tượng" và "Hướng đối tượng" .

Công văn năng động của các hoạt động là đặc tính thiết yếu của các đối tượng. Nó có nghĩa là hoạt động được gọi là một thuộc tính động của chính đối tượng. Các hoạt động không thể được xác định một cách tĩnh và nói chung không có cách nào để chính xác hoạt động nào sẽ được thực hiện để đáp ứng với một yêu cầu nhất định, ngoại trừ bằng cách chạy nó. Điều này hoàn toàn giống với các hàm hạng nhất, luôn được gửi động.

Trong Smalltalk-72, thậm chí không có bất kỳ đối tượng nào! Chỉ các dòng tin nhắn được phân tích cú pháp, viết lại và định tuyến lại. Các phương thức xuất hiện đầu tiên (các cách tiêu chuẩn để phân tích và định tuyến lại các luồng thông báo), sau đó là các đối tượng (các nhóm phương thức chia sẻ một số trạng thái riêng tư). Kế thừa xuất hiện muộn hơn nhiều và các lớp chỉ được giới thiệu như một cách để hỗ trợ kế thừa. Nếu nhóm nghiên cứu của Kay đã biết về các nguyên mẫu, có lẽ họ sẽ không bao giờ giới thiệu các lớp học ở nơi đầu tiên.

Benjamin Pierce trong các loại và ngôn ngữ lập trình lập luận rằng tính năng xác định của Định hướng đối tượng là đệ quy mở .

Vì vậy: theo Alan Kay, OO là tất cả về nhắn tin. Theo William Cook, OO là tất cả về công văn phương thức động (đó thực sự là điều tương tự). Theo Benjamin Pierce, OO là tất cả về Open Recursion, về cơ bản có nghĩa là tự tham chiếu được giải quyết một cách linh hoạt (hoặc ít nhất đó là một cách để suy nghĩ), hay nói cách khác là nhắn tin.

Như bạn có thể thấy, người đặt ra thuật ngữ "OO" có một cái nhìn khá siêu hình về các vật thể, Cook có một cái nhìn khá thực dụng và xuyên thủng một quan điểm toán học rất nghiêm ngặt. Nhưng điều quan trọng là: nhà triết học, nhà thực dụng và nhà lý luận đều đồng ý! Nhắn tin là một trụ cột của OO. Giai đoạn = Stage.

Lưu ý rằng không có đề cập đến thừa kế ở đây! Kế thừa là không cần thiết cho OO. Nói chung, hầu hết các ngôn ngữ OO có một số cách thực hiện sử dụng lại nhưng điều đó không nhất thiết phải là sự kế thừa. Nó cũng có thể là một số hình thức ủy quyền, ví dụ. Trên thực tế, Hiệp ước Orlando thảo luận về sự ủy thác như là một sự thay thế cho sự kế thừa và cách thức các hình thức ủy quyền và kế thừa khác nhau dẫn đến các điểm thiết kế khác nhau trong không gian thiết kế của các ngôn ngữ đối tượng. (Lưu ý rằng thực sự ngay cả trong các ngôn ngữ hỗ trợ kế thừa, như Java, mọi người thực sự được dạy để tránh điều đó, một lần nữa cho thấy rằng nó không cần thiết cho OO.)


1
@DavidArno Nhận xét của bạn không mang tính xây dựng. Bản thân Alan Kay tuyên bố ông đặt ra thuật ngữ "đối tượng" cho khái niệm này (mặc dù, tôi cho rằng, không phải bản thân khái niệm này). Nếu bạn sẽ mâu thuẫn với một cơ quan nổi tiếng về chủ đề này, ít nhất hãy viết một bình luận mang tính xây dựng hơn.
Andres F.

1
@DavidArno Ngoài ra, là downvote của bạn? Vì vậy, ai đó đã dành thời gian để viết một danh sách toàn diện các quan điểm khác nhau, từ các chuyên gia nổi tiếng, về ý nghĩa của OOP và bạn đã đánh giá thấp nó vì bạn không đồng ý với một câu? Oookay.
Andres F.

2
@AresresF. Câu trả lời này có thể được tóm tắt là "mặc dù có hai trường phái là Alan Kay và những người khác. Bởi vì trước đây, thuật ngữ này tự động anh ta đúng và mọi người không đồng ý với anh ta đều sai". Đó là một lời kêu gọi để trả lời ngụy biện thẩm quyền. Do đó, downvote.
David Arno

2
Trên thực tế, câu trả lời này có thể được tóm tắt là "có ba trường phái suy nghĩ, đến từ ba góc độ hoàn toàn khác nhau và không ai không đồng ý với bất kỳ ai, trên thực tế, tất cả đều đồng ý." Nhà phân tích ngôn ngữ sẽ nói, Alan Kay đã phát minh ra thuật ngữ này, anh ta có thể nói ý nghĩa của nó và anh ta nói nó có nghĩa là nhắn tin. Nhà mô tả ngôn ngữ sẽ nói, không, Alan Kay không nói gì cả, chúng ta phải xem thuật ngữ này thực sự được sử dụng như thế nào và đó là những gì Cook đã làm: ông đã nghiên cứu những ngôn ngữ thường được mô tả là OO (Java, C ++ , C #, v.v.) có điểm chung, và anh đã tìm thấy
Jörg W Mittag

3
một điều: nhắn tin. Ông đã nghiên cứu những ngôn ngữ thường được mô tả là không phải OO đang thiếu những ngôn ngữ thường được mô tả là OO và ông đã tìm thấy một điều: nhắn tin. Nhà lý thuyết tháp ngà lấy phép tính và xem xét tập hợp các tính năng nhỏ nhất mà người ta sẽ phải thêm vào để có được thứ gì đó thường được mô tả là OO, và anh ta đến đệ quy mở , về cơ bản là khối xây dựng để nhắn tin .
Jörg W Mittag

3

Như @Philipp tuyên bố, gốc rễ của vấn đề là không có định nghĩa chính thức về những gì làm cho ngôn ngữ lập trình hướng đối tượng. Thật vậy, đây có lẽ là một điều tốt. Có rất nhiều cách để hỗ trợ lập trình OO, mỗi cách đều có ưu điểm và nhược điểm riêng. Thảo luận về ngôn ngữ nào "OO thuần túy" hơn thực sự không đạt được nhiều.

Tuy nhiên, nhìn vào 5 thuộc tính bạn liệt kê, theo tôi, Modularity chắc chắn là một thuộc tính kỳ quặc. Modularity thực sự là một thuộc tính của một chương trình không phải là ngôn ngữ lập trình. Ở cấp độ ngôn ngữ, thuộc tính là "hỗ trợ cho việc mô đun hóa" và thường có dạng cơ chế "mô-đun" pr "gói".

Nhưng sự phản đối thực sự của tôi đối với Modularity là nó không phải là chìa khóa đối với các ngôn ngữ lập trình OO hoặc lập trình OO, đến mức mà ngôn ngữ lập trình nguyên mẫu Smalltalk-80 hoàn toàn không hỗ trợ các mô-đun. Và khi bạn nghĩ về nó, hỗ trợ ngôn ngữ cho các mô-đun trong nhiều OOPL được sử dụng rộng rãi là "yếu".

Các mô-đun được thiết kế để hỗ trợ "lập trình lớn" ... trong đó cơ sở mã của bạn quá lớn để một người có thể hiểu đầy đủ. Và bạn không cần các mô-đun trong ngôn ngữ lập trình để mô đun hóa mã của bạn.


Tôi cũng không tham gia vào cuộc tranh luận về 4 thuộc tính khác và liệu (ví dụ) mô hình "thừa kế" nào là OO thuần túy. Ngoài ra, trong khi Alan Kay được cho là đã phát minh ra lập trình OO, điều đó không nhất thiết có nghĩa là các định nghĩa về OO / và OOPL của anh ta có tính ưu việt. Rõ ràng nó không phải như thế. Ông là một nguồn có thẩm quyền, nhưng có những nguồn khác đưa ra các định nghĩa khác cho OO & OOPL mà (trong thực tế) mang trọng lượng lớn hơn.


2
+1 Modularity trên thực tế được chấp nhận rộng rãi như một thuộc tính mong muốn của hầu hết các hệ thống phần mềm, bất kể ngôn ngữ lập trình và mô hình được sử dụng. Nhiều ngôn ngữ không phải là OO có hỗ trợ mô đun hóa.
Andres F.

+1 @AndresF. bình luận. Thật vậy, "lập trình có cấu trúc" và "tinh chỉnh từng bước" (một kỹ thuật để suy nghĩ cấu trúc mã) xuất phát từ "sự phức tạp gia tăng dẫn đến phần mềm thậm chí còn tồi tệ hơn". Nếu nó đi trước COBOL thì ngôn ngữ sẽ không có tiếng xấu như vậy IMHO. Và tôi xem OO một cách thực tế như cấu trúc đơn hàng cao hơn. Và tôi có nghĩa là w / out cấu trúc cơ bản OO không tốt hơn so với COBOL tồi tệ nhất.
radarbob
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.