Trong học kỳ đầu tiên, chúng tôi đã được giới thiệu các khái niệm OOP như đóng gói, ẩn dữ liệu, mô đun hóa, kế thừa, v.v. thông qua Java và UML. (Java là ngôn ngữ lập trình đầu tiên của tôi)
Không ai trong số đó là khái niệm OOP. Tất cả đều tồn tại bên ngoài OO, độc lập với OO và nhiều người thậm chí đã được phát minh trước OO.
Vì vậy, nếu bạn nghĩ rằng đó là tất cả những gì về OO, thì kết luận của bạn là đúng: bạn có thể thực hiện tất cả những điều đó bằng ngôn ngữ thủ tục, vì chúng không liên quan gì đến OO .
Ví dụ, một trong những bài báo chuyên đề về Modularity là về Tiêu chí được sử dụng trong việc phân tách các hệ thống thành các mô-đun . Không có đề cập đến OO trong đó. (Nó được viết vào năm 1972, khi đó OO vẫn còn là một khoảng trống tối nghĩa, mặc dù đã hơn một thập kỷ.)
Mặc dù Trừu tượng dữ liệu rất quan trọng trong OO, nhưng đó là hệ quả của tính năng chính của OO (Nhắn tin) hơn là một tính năng xác định. Ngoài ra, điều rất quan trọng cần nhớ là có nhiều loại trừu tượng dữ liệu khác nhau . Hai loại trừu tượng dữ liệu phổ biến nhất được sử dụng hiện nay (nếu chúng ta bỏ qua "không trừu tượng hóa gì", có lẽ vẫn được sử dụng nhiều hơn hai loại kết hợp khác), là các loại và đối tượng dữ liệu trừu tượng . Vì vậy, chỉ bằng cách nói "Ẩn thông tin", "Đóng gói" và "Trừu tượng dữ liệu", bạn đã không nói gì về OO, vì OO chỉ là một dạng Trừu tượng dữ liệu và hai thực tế là khác nhau về cơ bản:
- Với các kiểu dữ liệu trừu tượng, cơ chế trừu tượng hóa là hệ thống kiểu ; nó là hệ thống loại che giấu việc thực hiện. (Hệ thống loại không nhất thiết phải là tĩnh.) Với Đối tượng, việc triển khai bị ẩn sau giao diện thủ tục , không yêu cầu loại. (Ví dụ, nó có thể được thực hiện với các bao đóng, như được thực hiện trong ECMAScript.)
- Với các loại dữ liệu trừu tượng, các phiên bản của các ADT khác nhau được gói gọn với nhau, nhưng các phiên bản của cùng một ADT có thể kiểm tra và truy cập vào đại diện và thực hiện riêng tư của nhau. Đối tượng luôn được gói gọn từ mọi thứ . Chỉ bản thân đối tượng có thể kiểm tra đại diện của chính nó và truy cập vào việc thực hiện riêng tư của chính nó. Không có đối tượng nào khác , thậm chí không phải các đối tượng khác cùng loại, các thể hiện khác của cùng một lớp, các đối tượng khác có cùng nguyên mẫu, bản sao của đối tượng hoặc bất cứ điều gì có thể làm điều đó. Không có .
Nhân tiện, điều này có nghĩa là trong Java, các lớp không hướng đối tượng. Hai trường hợp của cùng một lớp có thể truy cập đại diện riêng và thực hiện riêng tư của nhau. Do đó, các thể hiện của các lớp không phải là các đối tượng, thực tế chúng là các thể hiện ADT. Java interface
s, tuy nhiên, làm cung cấp hướng đối tượng dữ liệu trừu tượng. Vì vậy, nói cách khác: chỉ các thể hiện của giao diện là các đối tượng trong Java, các thể hiện của các lớp thì không.
Về cơ bản, đối với các loại, bạn chỉ có thể sử dụng giao diện. Điều này có nghĩa là các kiểu tham số của phương thức và hàm tạo, trả về kiểu phương thức, kiểu trường thể hiện, trường tĩnh và trường cục bộ, đối số cho instanceof
toán tử hoặc toán tử truyền và đối số kiểu cho hàm tạo kiểu chung phải luôn là giao diện. Một lớp chỉ có thể được sử dụng trực tiếp sau new
toán tử, không ở đâu khác.
Ví dụ, đối với tính mô đun, chúng ta chỉ có thể chia chương trình thành nhiều chương trình nhỏ thực hiện các tác vụ được xác định rõ có mã được chứa trong các tệp riêng biệt. Các chương trình này sẽ tương tác với nhau thông qua đầu vào và đầu ra được xác định rõ. Các tập tin có thể được bảo vệ (mã hóa?) Để đạt được đóng gói. Để sử dụng lại mã, chúng ta chỉ cần gọi các tệp đó bất cứ khi nào cần trong các chương trình mới. Điều này không nắm bắt được tất cả những gì OOP là hay tôi đang thiếu một cái gì đó rất rõ ràng?
Những gì bạn mô tả là OO.
Đó thực sự là một cách tốt để suy nghĩ về OO. Trên thực tế, đó chính xác là những gì mà các nhà phát minh ban đầu của OO đã nghĩ đến. (Alan Kay đã tiến thêm một bước: anh ta hình dung rất nhiều máy tính nhỏ gửi tin nhắn cho nhau qua mạng.) Cái mà bạn gọi là "chương trình" thường được gọi là "đối tượng" và thay vì "gọi" chúng ta thường nói "gửi tin nhắn" ".
Định hướng đối tượng là tất cả về Nhắn tin (còn gọi là công văn động ). Thuật ngữ "Hướng đối tượng" được đặt ra bởi Tiến sĩ Alan Kay, nhà thiết kế chính của Smalltalk, và ông định nghĩa nó như thế nà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à ràng buộc cực kỳ muộn của 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
- được 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 trễ-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 được nhiều hơn là thiết kế cách thức 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 để [biết] chính xác thao tác 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á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.)