Các tính năng cần thiết cho Định hướng đối tượng là gì?


9

Tôi chỉ tự hỏi, chính xác các tính năng mà một ngôn ngữ hoặc thư viện phải cung cấp để được định nghĩa là 'Định hướng đối tượng' là gì. Là Định hướng đối tượng một cái gì đó có thể, ít nhiều, có thể đạt được trong bất kỳ ngôn ngữ lập trình có mục đích chung nào với các tính năng hợp lý? Hay đó là thứ chỉ có thể đạt được bằng các ngôn ngữ quảng cáo cụ thể rằng chúng hỗ trợ Lập trình hướng đối tượng?

Ví dụ, xem mã C sau đây:

SDL_Surface* screen = SDL_SetVideoMode( 640, 480, 16, SDL_HWSURFACE);
SDL_FreeSurface( screen );

hoặc mã được thảo luận ở đây .

Bây giờ đoạn mã trên không sử dụng tính kế thừa, đa hình thời gian chạy (?), Các hàm ảo, v.v. Nhưng nó có vẻ khá nhiều OOP đối với tôi.

Có phải Định hướng đối tượng chỉ đơn giản là viết mã dựa trên các cấu trúc dữ liệu có thể tạo và phá hủy như các đối tượng, lớp, cấu trúc, v.v. không yêu cầu bất kỳ mẫu hoặc tính năng đặc biệt nào được cung cấp bởi Ngôn ngữ lập trình hoặc thư viện ?


2
OOP thường yêu cầu các đối tượng . Tuy nhiên, có thể viết mã trông OOP bằng hầu hết các ngôn ngữ (tôi nghi ngờ bạn có thể nói "hội đồng này trông OOP")
Raynos

Đoạn mã trên không sử dụng một nếu tuyên bố hoặc một vòng lặp . Nó không sử dụng phép nhân hoặc phép cộng. Bạn không thể sử dụng hai dòng mã và một danh sách những thứ không được hiển thị để đưa ra bất kỳ phán xét nào. Từ hai dòng mã đó, tôi có thể suy luận rằng đó là ngôn ngữ lập trình chức năng hoàn toàn lười biếng, không phải là ngôn ngữ OO. Sử dụng hai dòng mã như một phần của khái quát hóa không phải là một câu hỏi thực sự.
S.Lott

Các liên kết cũng được bao gồm trong các mã trên mà tôi đánh giá thuận. Cũng lưu ý rằng đó không phải là một bản án , tôi đang hỏi bạn liệu điều này có thể được coi là OOP không.
Người học việc

Câu trả lời tầm thường là . Quan điểm của tôi là thế này. Bạn không thể - từ các ví dụ mã - đưa ra đánh giá về OOP. Đó là một vấn đề tầm thường của định nghĩa. Ngôn ngữ được định nghĩa là ngôn ngữ OOP hoặc ngôn ngữ không. Bất kỳ mẫu mã nhất định có thể không yêu cầu tất cả các tính năng OOP. Thật vậy, mã OOP có thể sử dụng rất, rất ít tính năng. Trong Python, ví dụ, 1+2thực sự là hướng đối tượng. Nó là một constructor xây dựng một đối tượng mới từ hai đối tượng hiện có. Sử dụng mẫu mã cho thấy không có gì.
S.Lott

Có gì sai khi sử dụng định nghĩa này và so sánh nó với ngôn ngữ (không phải hai mẫu mã)? vi.wikipedia.org/wiki/ từ
S.Lott

Câu trả lời:


11

Theo Alan Kay, người đã phát minh ra thuật ngữ "hướng đối tượng",

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ứ. Nó có thể được thực hiện trong Smalltalk và LISP. Có thể có các hệ thống khác trong đó điều này là có thể, nhưng tôi không biết về chúng.

Nhắn tin (như được triển khai trong Smalltalk) là một khái niệm có thể so sánh với đa hình, nhưng mạnh hơn (ít nhất là loại đa hình được hỗ trợ bởi C ++ hoặc Java). Nó có thể được thực hiện bằng tất cả các ngôn ngữ, nhưng khá đau đớn nếu không được ngôn ngữ hỗ trợ trực tiếp. Về cơ bản, điều đó có nghĩa là các đối tượng có thể gửi cho nhau các tin nhắn có chứa bất cứ thứ gì, amd có thể phản ứng tuy nhiên họ muốn tin nhắn họ nhận được. Để hỗ trợ đầy đủ cho việc nhắn tin, phải có cách để các đối tượng phản ứng linh hoạt với các tin nhắn mà không liệt kê chúng trong mã nguồn (về cơ bản là định nghĩa phương thức / hàm làm gì).

duy trì và bảo vệ cục bộ và che giấu quá trình nhà nước - đóng gói AKA - có thể được thực hiện theo quy ước trong tất cả các ngôn ngữ, nhưng điều đó phần nào gian lận. Duy trì cục bộ ở cấp độ ngôn ngữ dường như là một tính năng mà tất cả các ngôn ngữ tự xưng là OO (và nhiều ngôn ngữ không chia sẻ) - nói chung có một cách để tạo các kiểu dữ liệu ghép với nhiều trường hợp. Mặt khác, việc bảo vệ và che giấu thường chỉ được thực hiện theo quy ước.

ràng buộc muộn của tất cả mọi thứ - một thang trượt mà C thực sự ở rất xa tầm nhìn của Kay (Cũng như C ++, trong khi Java gần hơn nhiều). Có thể bị làm giả (xem COM), nhưng đó sẽ là một nỗi đau để sử dụng.

Lưu ý làm thế nào Kay không đề cập đến thừa kế . Trong cùng một email anh ấy đã viết

Tôi không thích cách Simula I hay Simula 67 thực hiện kế thừa (mặc dù tôi nghĩ Nygaard và Dahl chỉ là những nhà tư tưởng và nhà thiết kế vĩ đại). Vì vậy, tôi quyết định loại bỏ quyền thừa kế như một tính năng tích hợp cho đến khi tôi hiểu rõ hơn về nó


4
Chính xác thì Java và C # gần với ràng buộc muộn hơn C ++ như thế nào?
dòng chảy

@FredOverflow: Java lười biếng tải các định nghĩa lớp khi chạy lần đầu tiên và chúng hoàn toàn thông qua một cơ chế cực kỳ linh hoạt, dễ dàng cho phép thêm các lớp mới hoặc thậm chí tạo chúng một cách nhanh chóng. C ++ yêu cầu bạn phải xem lại các thư viện tải thực thi hoặc tải rõ ràng của bạn. Tình hình với C # dường như chưa rõ ràng hơn tôi nghĩ, vì vậy tôi đã xóa tham chiếu đến ti.
Michael Borgwardt

5

Lập trình hướng đối tượng không phải là về các tính năng cú pháp, nó là một cấu trúc mã hóa và thiết kế. Tại cốt lõi của nó là khái niệm về một đối tượng , đó là một cấu trúc mà các nhóm nêu ra các thói quen để hành động theo nó (hoặc, tùy theo quan điểm của bạn, phản hồi các tin nhắn). Khía cạnh quan trọng khác của OOP là đóng gói : gói các chi tiết triển khai vào các cấu trúc mờ và kết nối chúng thông qua các giao diện được xác định rõ. Khá nhiều thứ khác trong lý thuyết OOP quay trở lại hai nguyên tắc cơ bản này.

Vì vậy, bất kỳ ngôn ngữ nào bằng cách nào đó có thể mô hình hóa các đối tượng (các thực thể chứa cả dữ liệu và mã) và đóng gói có thể được sử dụng để thực hiện OOP. Ví dụ, trong C, bạn có thể sử dụng các con trỏ hàm để lưu trữ các hàm trong các cấu trúc và bạn có thể sử dụng hệ thống tệp tiêu đề / nguồn để thực hiện đóng gói. Nó không thuận tiện, nhưng nó là đủ để làm OOP. Bạn thậm chí có thể biến một cái gì đó như Haskell hoặc ML thành OOP, và tôi sẽ không ngạc nhiên nếu ai đó có thể nghĩ ra cách lắp ráp OOP.

Tuy nhiên, thực tế mà nói, một ngôn ngữ có thể được gọi là 'hướng đối tượng' nếu nó cung cấp một bộ đầy đủ các tính năng cú pháp cho lập trình hướng đối tượng rõ ràng. Thông thường, điều này có nghĩa là một ngôn ngữ như vậy nên có: * một khái niệm về một đối tượng * một khái niệm về phương thức gọi hoặc tin nhắn truyền * một cách thoải mái và đơn giản để kiểm soát truy cập vào các thành viên đối tượng * một cách dễ dàng và đơn giản để xác định giao diện

Do đó, tôi sẽ gọi một đoạn mã hướng đối tượng nếu nó tuân thủ các nguyên tắc OOP và sử dụng cú pháp OOP có sẵn.

BTW., Ví dụ mã của bạn có thể không sử dụng đa hình và chức năng ảo, mặc dù cú pháp C không làm cho nó rõ ràng. Tôi không phải là chuyên gia về SDL, nhưng tôi hy vọng SDL_surfacecó thể đại diện cho nhiều loại bề mặt khác nhau, mỗi loại có một bộ triển khai cụ thể của riêng nó - làm mờ một cái gì đó lên một bitmap bộ nhớ và làm mờ bề mặt màn hình đòi hỏi phải hoàn toàn khác mã, nhưng giao diện (các hàm lấy SDL_surface*làm đối số) vẫn giữ nguyên. Giống như vậy, nó cũng thực hiện đóng gói: bạn không thể truy cập trực tiếp vào biểu diễn bên dưới của bề mặt, bạn phải thực hiện các chức năng biết cách xử lý SDL_surface, vì đó là tất cả những gì bạn có. Đó là một ví dụ hay về cách bạn làm OOP trong C.


Mặc dù vậy, các kiểu dữ liệu trừu tượng, mô hình hóa dữ liệu và đóng gói không phải là duy nhất đối với OO (như bạn đề cập ngắn gọn về bản thân). Tôi muốn mô tả OO dựa trên các tính năng độc đáo hơn của nó (ràng buộc động của các cuộc gọi phương thức, tính đa hình thông qua các cuộc gọi phương thức đã nói, v.v.)
hugomg

4

Hiểu biết của tôi về OO là OO là một cách suy nghĩ và thực hiện dựa trên ý tưởng rằng một nhiệm vụ tính toán có thể đạt được bởi một công nhân (đối tượng) hoặc bằng sự cộng tác của từng công nhân (đối tượng) thông qua tin nhắn giữa những công nhân đó ( các đối tượng) tại thời gian chạy. Hành vi thời gian chạy này đòi hỏi các cấu trúc tĩnh và động để kích hoạt nó.

Cú pháp cụ thể để thực hiện OO không phải là chìa khóa quyết định liệu ngôn ngữ có phải là OO hay không. Ví dụ, Smalltalk và C # có các cú pháp khác nhau nhưng cả hai đều là ngôn ngữ OO (ở một mức độ khác nhau). Điều quan trọng là liệu ngôn ngữ đã cho có bảo tồn triết lý (ở trên) và cung cấp các phương tiện cấy ghép cần thiết hay không.


2

Khi còn là sinh viên, tôi được dạy rằng lập trình hướng đối tượng đứng trên ba trụ cột:

  • đóng gói ,
  • đa hình , và
  • thừa kế .

Một ngôn ngữ sẽ phải hỗ trợ các tính năng đó để được coi là ngôn ngữ hướng đối tượng.

Lưu ý rằng điều này mô tả một tập hợp các tính năng, thay vì cú pháp . Do đó, cho dù bạn phải viết

type obj; // or type obj = new type;
obj.func(arg);

hoặc là

type* ptr = create_type();
func(ptr, arg); 

không quan trọng

Vì vậy, bạn thực sự có thể lập trình theo mô hình hướng đối tượng trong C. Nhưng ngôn ngữ không cung cấp hỗ trợ cho việc này, điều này làm cho nó trở thành một bài tập khá đau đớn. Đây là lý do tại sao C không được coi là một ngôn ngữ hướng đối tượng.


2
Dạy những "trụ cột" này có lẽ đã gây hại nhiều hơn là tốt cho thế giới. Đóng gói là tốt, nhưng đó là về nó.
tdammers

1
Họ nằm trong danh sách này, vì vậy họ dường như được chấp nhận rộng rãi: en.wikipedia.org/wiki/ Kẻ
S.Lott

Bạn có thể giải thích tại sao đa hình và kế thừa là xấu?
MathAttack

@MathAttack: Bạn đang nói chuyện với tôi? Bởi vì tôi chắc chắn đã không nói như vậy.
sbi

1
@missingno: Một cái gì đó không phải là duy nhất đối với một số mô hình để được coi là quan trọng để phân biệt mô hình. Đóng gói không còn phải là duy nhất cho OOP vì các hàm phải là duy nhất cho lập trình có cấu trúc.
sbi

2

Bạn có thể thực hiện OO bằng bất kỳ ngôn ngữ có mục đích chung nào.

Làm điều đó dễ dàng hơn bằng ngôn ngữ "OO", bởi vì bạn có sẵn các cấu trúc thành ngữ và không phải dùng đến một thứ như OO trong C - điều này là có thể, nhưng thật kinh khủng.

Việc các cấu trúc OO được cung cấp bởi chính ngôn ngữ, bởi thư viện chuẩn của nó hay bởi một số thư viện khác, không quan trọng lắm, vì một số ngôn ngữ (ví dụ Scala) cho phép các thư viện thêm các cấu trúc ngôn ngữ để theo quan điểm của lập trình viên, điều đó gần như không thể để phân biệt những thứ được cung cấp bởi ngôn ngữ cốt lõi và thư viện nào.


2

Nếu bạn nhìn vào phạm vi các ngôn ngữ đã được chấp nhận rộng rãi như OO và những ngôn ngữ chưa có, thì bài kiểm tra dường như là sự hỗ trợ cho đa hình bao gồm (đa hình loại phụ, nhưng đa hình bao gồm là thuật ngữ được Cardelli sử dụng trong giấy giới thiệu cho tôi, và tôi nghĩ khá nhiều người khác, để phân loại các loại đa hình). IE khả năng một số biến có các giá trị thuộc các loại khác nhau và khả năng một số lệnh gọi gửi đến các thói quen khác nhau tùy thuộc vào loại của một hoặc một vài giá trị. Mọi thứ khác đã có mặt trong các ngôn ngữ không được chấp nhận là OO hoặc bị thiếu trong các ngôn ngữ được chấp nhận tốt như OO.

Hai đặc điểm chính khác liên quan đến các ngôn ngữ OO đã được cung cấp bởi các ngôn ngữ không phải OO:

  • Đóng gói được cung cấp khá tốt bởi Ada83;
  • Quyền thừa kế được cung cấp bởi Oberon (Oberon rất thú vị, Wirth muốn cung cấp một ngôn ngữ OO càng ít càng tốt, nhưng phải xem lại quan niệm của mình để có được một - Oberon-2 là OO).

1

Hướng đối tượng được định nghĩa là

cũng kiểm tra các mục wikipedia. đó là những tính năng mà ngôn ngữ phải cung cấp để được định nghĩa là hướng đối tượng.

xem xét đối tượng mã của bạn theo định hướng nếu nó nằm trong ngôn ngữ lập trình hướng đối tượng. ngay cả khi bạn viết một cái gì đó có vẻ là thủ tục, nó sẽ tác động lên các phương thức trong các đối tượng từ các lớp bằng cách sử dụng đa hình thông qua đóng gói [có thể] :)

Về câu hỏi cuối cùng của bạn, câu trả lời có lẽ là. Đúng. hướng đối tượng về cơ bản chỉ là hành động trên các phương thức trên các đối tượng và truyền xung quanh các đối tượng đó làm tham số.


3
Xác định bởi ai?
Michael Borgwardt
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.