Có sự khác biệt nào khi học OOP trên các ngôn ngữ lập trình khác nhau không? [đóng cửa]


9

Tôi muốn học OOP. Tôi biết Python và tôi biết rất ít điều về OOP.

Nhưng khi tôi tìm kiếm "học OOP" trên các diễn đàn, tôi thấy một anh chàng nói rằng "Python rất mới, đó là lý do tại sao bạn không thể học OOP trên Python. Bạn nên học Java sau đó hiểu OOP trên Java"

Có đúng không Có sự khác biệt nào hiểu OOP trên các ngôn ngữ lập trình khác nhau không? thích học nó trên Java, C #, C ++, Perl hay Python?


12
"Python rất mới, đó là lý do tại sao bạn không thể học OOP trên Pyton. Bạn học Java sau đó hiểu OOP trên Java" Điều đó không có nghĩa gì với tôi. Nếu bạn muốn học OOP bằng Python, tôi không thấy lý do nào cả. Cứ liều thử đi!
Thất vọngWithFormsDesigner

13
Không phải Python cũ hơn Java sao? Tôi không thể tin được, nhưng tôi có thể nghỉ một vài năm.
Jimmy Hoffa

2
@JimmyHoffa Quả thực là vậy. 91 so với 95 theo Wikipedia.
Evicatos

2
@JimmyHoffa: thôi nào, điều đó không thể là sự thật, phải không! Chúng ta đều biết Java là ngôn ngữ OO đầu tiên. "Sun lớn tiếng báo hiệu sự mới lạ của Java" ... - Đối với câu hỏi ... tại sao bạn quyết tâm học OO? Điều đó sẽ buộc bạn phải sớm thôi. Python là một điểm khởi đầu tuyệt vời, để hiểu rõ hơn về lợi ích của nhiều mô hình lập trình.
leftaroundabout

Câu trả lời:


10

Một đối tượng như một cấu trúc lý thuyết rất đơn giản: Đó là một cấu trúc lưu trữ dữ liệu, chức năng hoặc cả hai. Ý tưởng là các cấu trúc này có ý nghĩa về "bản thân", ẩn trong hầu hết các ngôn ngữ bên ngoài Python. Đây được gọi là "mô tả" và cung cấp cho đối tượng một điểm tự tham chiếu liên kết dữ liệu (biến hoặc trường) và các hàm (thường được gọi là phương thức) với đối tượng cụ thể được đề cập. Ý tưởng là bạn đang sử dụng một biến hoặc phương thức cụ thể thuộc về trường hợp cụ thể đó (khối bộ nhớ được phân bổ thường ở bên dưới) thay vì một số cấu trúc tổng quát hơn, lớn hơn.

Các hệ thống đối tượng có xu hướng thay đổi liên quan đến hai loại lớn: Kế thừa và Truy cập.

Một số, như Java hoặc C ++, bạn có khai báo các lớp đóng vai trò là "bản thiết kế" cho các đối tượng sau đó được phân bổ. Các lớp này và các đối tượng của chúng không thể được sửa đổi cấu trúc một khi được khởi tạo. Họ có thể có nội dung của họ bị ghi đè theo nghĩa các biến có thể thay đổi nhưng cấu trúc của chúng là tĩnh. Ví dụ, bạn không thể thêm các phương thức mới vào HashMap trong Java. Bạn có thể mở rộng giao diện (về cơ bản là các lớp được triển khai dưới dạng hợp đồng) hoặc tạo một lớp con để có được các phương thức hoặc biến bổ sung mà bạn cần cùng với tất cả các biến và phương thức ban đầu của lớp cụ thể được đề cập.

Các ngôn ngữ dựa trên lớp khác, ngôn ngữ được trích dẫn điển hình nhất là Ruby, cho phép bạn dễ dàng mở một lớp hiện có và chỉ cần thêm các phương thức khi bạn thấy phù hợp. Đây là một xương của sự tranh chấp và được nhiều người coi là rất, rất nguy hiểm.

Javascript thậm chí còn lỏng lẻo hơn, Đối tượng không có gì khác ngoài một bộ sưu tập các vị trí cho các biến hoặc hàm. Chúng có thể được thay đổi hoặc ghi đè bất cứ khi nào lập trình viên cảm thấy cần phải làm như vậy. Chúng thậm chí có thể được nhân bản tùy ý thành "Nguyên mẫu" cho các đối tượng khác, do đó chuyển tất cả các khả năng của chúng vào.

Kiểm soát truy cập là điểm khác biệt lớn khác giữa các ngôn ngữ khác nhau.

Một số ngôn ngữ như Java có các bộ sửa đổi truy cập được thi hành rất nghiêm ngặt như "riêng tư" và "được bảo vệ", xác định chính xác những lớp và lớp con nào có thể sử dụng một biến hoặc phương thức đã cho.

Những người khác, chẳng hạn như Python ít trang trọng hơn, sử dụng quy ước của dấu gạch dưới trước phương thức hoặc tên biến để chỉ ra rằng nó là riêng tư.

Cuối cùng, Python là một ngôn ngữ hoàn toàn hợp pháp để lập trình theo kiểu hướng đối tượng, nó chỉ không thực thi nó một cách nghiêm ngặt như một số ngôn ngữ khác.


Có thể là một chút quá kỹ thuật cho câu hỏi này.
Zeroth

@zeroth, và quá cụ thể quá. Tham số 'tự' (hoặc 'này') khác xa với phổ quát.
Javier

@Javier Đó là lý do tại sao tôi nói rằng nó rõ ràng bằng Python và ẩn ở nơi khác.
Kỹ sư thế giới

Câu hỏi là về việc học OOP và tôi nghĩ rằng thảo luận về cách một ngôn ngữ được viết để thực hiện một số khái niệm nhất định như Encapsulation nơi chúng ta có privatecho Java và gạch dưới ( __) cho Python là khá quan trọng. Tôi nghĩ mức độ trừu tượng của Python có thể làm cho nó khó khăn hơn một chút đối với người mới bắt đầu, nhưng chắc chắn không phải là không thể. Java đánh vần nó cho lập trình viên, điều này có thể làm cho một số khái niệm dễ dàng hơn một chút.
Derek W

@WorldEngineer Tôi không nói về việc rõ ràng / ẩn (ngoài ra, Python không phải là bất thường về điều này), mà chỉ đơn giản là tồn tại như một khái niệm. Một số ngôn ngữ thực hiện công văn đa hình trên tất cả các tham số, không chỉ trên đầu tiên. Một số sử dụng các gợi ý khác cho phiên bản cụ thể và kiểu chính có thể không đặc quyền cho một đối số là 'cái này'.
Javier

18

Học các nguyên tắc OOP hoàn toàn không phải là ngôn ngữ cụ thể, vì vậy nếu bằng cách "học OOP", bạn có nghĩa là "học thuật ngữ này nghĩa là gì, OOP là gì và tại sao tôi có thể muốn sử dụng nó" thì ngôn ngữ không thành vấn đề.

Nếu bạn có nghĩa là "học cách phát triển bằng OOP" thì có, các ngôn ngữ khác nhau xử lý nó khác nhau, nhưng tất cả chúng đều có chung một bộ nguyên tắc. Nếu bạn là bất cứ ai như tôi, bạn sẽ học nó tốt nhất bằng cách làm điều đó. Chọn một ngôn ngữ hướng đối tượng với một hướng dẫn hoặc cuốn sách hay bao gồm các khía cạnh hướng đối tượng và có nó. Nếu bạn có các nguyên tắc thiết kế hướng đối tượng, bạn sẽ có thể sử dụng chúng trong bất kỳ ngôn ngữ OO nào khác.

"Python rất mới, đó là lý do tại sao bạn không thể học OOP trên Pyton. Bạn học Java sau đó hiểu OOP trên Java"

Điều này chỉ làm cho đầu tôi đau. Quá nhiều sai lầm nhồi nhét vào một câu.

Python có từ năm 1989.

http://python-history.blogspot.com/2009/01/brief-timeline-of-python.html

Java đến 1995.

http://www.oracle.com/technetwork/java/javase/overview/javahistory-index-198355.html

Bạn có thể tự rút ra kết luận về tính hợp lệ của lời khuyên đó ...


1
Đúng nhưng Python 1.0 không tồn tại cho đến năm 1994. Java đã được phát triển khá lâu trước khi nó được phát hành. Nhưng tôi đồng ý rằng Python có OO và bạn CÓ THỂ tìm hiểu các khái niệm về OO. Thật vô lý khi nói khác.
chubbsondub

2
@chubbsondub Yep, vẫn còn trước Java! ;)
Izkata

1
Để chỉ cung cấp một điểm đối chiếu nhẹ, OOP dựa trên lớp (C ++, Java, Python và nhiều thứ khác) khá khác so với OOP dựa trên nguyên mẫu (JavaScript là ngôn ngữ duy nhất tôi biết sử dụng điều này). Họ vẫn là OOP và có cùng các nguyên tắc cơ bản và phục vụ rất nhiều mục tiêu giống nhau, nhưng nhiều người coi các lớp là một phần của những gì họ coi là OOP, trong khi JavaScript không có chúng và chắc chắn là hướng đối tượng.
KRyan

@KRyan: Trong trường hợp bạn quan tâm, có một ngôn ngữ OO dựa trên nguyên mẫu khác có tên là Self.
Jerry Coffin

ActionScript có cả nguyên mẫu và lớp.
OrangeDog

8

Tôi nghĩ rằng người bạn trích dẫn chỉ đơn giản là hiển thị chủ nghĩa sô vanh ngôn ngữ.

Trong thực tế, có một sự khác biệt giữa các khái niệm về OOP và việc thực hiện OOP. Về mặt thi pháp, điều này được hiểu rõ nhất một khi bạn nắm bắt tốt hơn một số khái niệm về OOP.

Rất nhiều lập trình viên trở nên thoải mái chỉ với một vài ngôn ngữ tương tự, vì vậy họ không phải mở rộng khả năng của mình hoặc chịu đựng không có khả năng trong một thời gian.

Vì vậy, câu hỏi đặt ra, thực sự, Python sẽ dạy bạn các khái niệm về OOP chứ?

Tôi sẽ nói bạn có thể, miễn là bạn có sự hỗ trợ học tập đầy đủ, thúc đẩy bạn thử những điều bạn thường không khám phá trong việc tự học. Một cuốn sách hoặc một người cố vấn của một số loại sẽ là tốt nhất. Mark Lutz viết những cuốn sách rất sâu sắc, rất chi tiết và rất xuất sắc về Python và tôi muốn giới thiệu những cuốn sách của anh ấy vì chúng sẽ thúc đẩy bạn làm và tìm hiểu thêm.

Điều bạn phải nhớ là cách của Python không phải là Cách duy nhất, cũng không phải là Cách duy nhất đúng. Bạn càng thành thạo nhiều mô hình lập trình, bạn sẽ trở thành một lập trình viên giỏi hơn. Cách Python thực hiện OOP không chính xác là cách C ++ hoặc Java thực hiện nó, nhưng các khái niệm chuyển giao tốt.


4
Về mặt OOP, Java và C ++ khác nhau nhiều như khác với Python.
Gort Robot

Ở một mức độ nào đó, nhưng điều đó phần lớn là do thay đổi kiến ​​thức thiết kế ngôn ngữ và các ràng buộc khác nhau.
Zeroth

Và thẳng thắn, 90% các khái niệm OOP chuyển giao tốt giữa chúng, gần như vô hình.
Zeroth

Yup, tôi đồng ý. Tôi thấy hơi buồn cười khi nghĩ rằng Java và C ++ là "giống nhau" về OOP.
Gort Robot

4

Có, triển khai OOP rất khác nhau. Tuy nhiên, lý thuyết và nguyên tắc là như nhau, nhưng rất nhiều người chỉ coi "OOP thực" là những gì Java và C ++ làm, rằng bạn nhận được nhiều tài liệu tham khảo được coi là "bất khả tri ngôn ngữ" nhưng thực tế lại cho rằng các ngôn ngữ được gõ tĩnh, dựa trên lớp .

Điều đó không có nghĩa là những tài liệu tham khảo đó là xấu, hoặc thậm chí hạn chế; ví dụ như cuốn sách "Nhóm bốn người" (GoF) "Các mẫu thiết kế: Các yếu tố của phần mềm hướng đối tượng có thể tái sử dụng" là một ví dụ điển hình của một tác phẩm tuyệt vời nói "OOP" khi nó thực sự có nghĩa là "OOP dựa trên lớp tĩnh".

Vì vậy, theo tôi: Có, bạn có thể học rất nhiều OOP trên Python, Javascript, C và nhiều ngôn ngữ khác; nhưng một số người (có thể là chủ nhân tương lai) khi yêu cầu "trải nghiệm OOP" có nghĩa là Java / C ++ / C #. Vì vậy, sẽ là khôn ngoan khi kiểm tra quan điểm khác quá.

(và đó không phải là hai 'loại' OOP duy nhất ....)


2
Trớ trêu thay, OOP dựa trên lớp tĩnh không phải là thứ mà Alan Key ban đầu đề xuất là OOP. Nhưng rất nhiều "học" OOP là về học thiết kế / ý nghĩa mã hóa không bị giới hạn nghiêm ngặt đối với việc triển khai OOP cụ thể
Daniel Gratzer

2
Cũng có thể có ý nghĩa khi xem CLOS: Tôi không nghĩ nhiều ngôn ngữ / khung cung cấp đa phương thức.
Giorgio

2
@jozefg: đúng, Alan Kay đã từng nói "Thực ra tôi đã tạo ra thuật ngữ" hướng đối tượng "và tôi có thể nói với bạn rằng tôi không có C ++ trong đầu."
Javier

1
@Giorgio Trên thực tế, Dylan có thể cung cấp một phiên bản CLOS đơn giản hơn một chút (không có cách nào để chỉ định khi đa phương thức được chạy, nhưng cách tiếp cận đơn giản hơn nhiều)
Daniel Gratzer

4

Lập trình hướng đối tượng là một ý tưởng về cách cấu trúc ngôn ngữ lập trình để thúc đẩy sự kết hợp thấp, ẩn thông tin (còn gọi là đóng gói), kết hợp dữ liệu và phương thức hoạt động trên dữ liệu đó với nhau và sử dụng lại mã. Rất nhiều ngôn ngữ triển khai thực hiện các ý tưởng này vì vậy có sự khác nhau giữa các ngôn ngữ về cách chúng tiếp cận Định hướng đối tượng. Ví dụ, Java chỉ cho phép một lớp mở rộng 1 lớp. Tuy nhiên, Python và C ++ cho phép bạn mở rộng bất kỳ số lượng lớp nào. Java có lý do cụ thể cho những hạn chế của nó. Những hạn chế có nghĩa là sửa những thứ từ C ++, nhưng cũng vì Smalltalk chỉ hỗ trợ một lớp cơ sở duy nhất.

Ngôn ngữ OO có thể được nhóm thành hai gia đình. Họ Smalltalk (hoặc OOP dựa trên lớp) của các ngôn ngữ bao gồm C ++, Java, Smalltalk, Ruby, C #, Python để đặt tên cho một số ít (có hàng tấn trong họ này). Đây là sự pha trộn của các ngôn ngữ loại tĩnh và động và trong khi chúng hơi khác nhau về một số khái niệm, chúng rất giống nhau về cách chúng nghĩ về OOP. Ý tôi là đó là cách họ tiếp cận khớp nối, đóng gói, ràng buộc dữ liệu và phương thức và tái sử dụng mã và các công cụ họ cung cấp cho bạn để làm điều đó. Trong gia đình này rất nhiều khái niệm là như nhau.

Các gia đình khác là OOP dựa trên protoype. Các ngôn ngữ này trông rất khác nhau trong việc thực hiện OOP của họ. Có lẽ ví dụ nổi tiếng nhất về điều này là Javascript, nhưng Javascript đã sao chép những ý tưởng này từ Scheme và Object LISP. Đây là những ngôn ngữ ít được biết đến và thường được gõ động. Tôi không thể nghĩ về một ngôn ngữ dựa trên nguyên mẫu được gõ tĩnh, nhưng điều đó không có nghĩa là không có ngôn ngữ. Bạn có thể đọc nó ở đây: http://en.wikipedia.org/wiki/Prototype-basing_programming . Vấn đề là họ tiếp cận OOP theo một cách rất khác so với các ngôn ngữ dựa trên lớp. Điều đó có nghĩa là các khái niệm không thể di động giữa hai gia đình này. Chỉ vì bạn biết OO trong một gia đình không có nghĩa là bạn sẽ dễ dàng chuyển những ý tưởng đó sang gia đình khác.

Hãy nhớ rằng hầu hết các ngôn ngữ lập trình trộn lẫn các khái niệm từ rất nhiều ý tưởng. Python và Ruby kết hợp cả OOP và ý tưởng lập trình chức năng vào ngôn ngữ của họ. Và bạn có thể trộn OO dựa trên nguyên mẫu với các phần mở rộng nhất định cho các ngôn ngữ dựa trên lớp để nó thậm chí còn phức tạp hơn.


Tôi sẽ không tính C ++ vào gia đình Smalltalk. Smalltalk dựa trên Simula và Alan Kay cố tình bỏ qua hầu hết các thay đổi trong Simula-II, trong khi C ++ dựa trên điều đó. C # thật lạ, nó được thiết kế bởi người dùng C ++ và nhà thiết kế Pascal giống như Java.
Jörg W Mittag

1

OOP là một nguyên tắc lập trình - về cơ bản đó là một ý tưởng. Việc triển khai OOP thay đổi trong các ngôn ngữ lập trình - nhưng các trụ cột (Trừu tượng hóa, Kế thừa, Đóng gói và Đa hình) của OOP thường xuất hiện theo một cách nào đó hoặc dưới dạng.

Tôi sẽ nói mà không ưu tiên cho bất kỳ ngôn ngữ nào, rằng Java thúc đẩy ngữ nghĩa khó hơn một chút đối với lập trình viên so với nói Python.

Ví dụ,

Mã Java: class Cat extends Animal {}

Rõ ràng hơn một chút về những gì bạn đang làm trong quan điểm OOP của mọi thứ hơn là:

Mã Python: class Cat(Animal):

Chắc chắn cả hai đều xác định một hệ thống phân cấp lớp trong đó Cat thừa hưởng từ Animal. Nhưng tôi cảm thấy rằng đối với một lập trình viên mới bắt đầu vào OOP, ứng dụng và ý nghĩa của các ý tưởng OOP có thể sẽ tốt hơn một chút trong Java vì nó đánh vần nó cho lập trình viên.


1

Bạn đang hỏi rõ ràng ngôn ngữ dễ nhất là gì để học các khái niệm OOP. Tôi nghĩ rằng câu trả lời là rõ ràng: trăn .

Để giải thích tại sao lại như vậy, chúng ta hãy xem chương trình dành cho người mới bắt đầu điển hình trong Java vs Python. Hãy làm một trò chơi đoán cao hơn đơn giản thấp hơn.

Java

Trong Java, bạn sẽ viết một lớp Game.

public class Game {
    public int secretNumber;
    public int tries;

    public Game(int tries, int secretNumber) {
        this.tries = tries;
        this.secretNumber = secretNumber;
    }

    public void guess(int myNumber) {
        if(myNumber > secretNumber)
            System.out.println("Your guess is too high!");
        else if (myNumber < secretNumber)
            System.out.println("Your guess is too low!");
        else
            System.out.println("You win!!");
        tries = tries - 1;
        if(tries == 0) {
            System.out.println("No more tries: you lose :(");
        }
    }

    public static void main(String[] args) {
        Game game = new Game(10, 47);
        while(true) {
            // how do I read a newline again? Something with BufferedInputStreamReader?
            // how do I convert a String to a number?
        }
    }
}

Tôi là một lập trình viên giàu kinh nghiệm, và thậm chí tôi đang gặp khó khăn. Hơn nữa, hãy nhìn vào những gì bạn cần giải thích cho một học sinh tương lai cho chương trình đơn giản này:

  • Phương thức tĩnh
  • Tầm nhìn (công khai vs riêng tư). Bạn phải luôn luôn đánh dấu các trường là riêng tư.
  • this. ký hiệu để chỉ các biến khi chúng bị che bởi những người khác
  • Hàm tạo giống như một phương thức, nhưng không phải là một phương thức.
  • System.outlà một đầu raStream. Và vâng, nó là một lĩnh vực, nhưng nó là một staticlĩnh vực.
  • Đôi khi, bạn có thể bỏ qua dấu ngoặc nhọn nếu chỉ có một câu lệnh
  • String[]là một mảng. Nó là một loại đối tượng đặc biệt, nhưng sau đó một lần nữa, không thực sự.
  • intlà một loại nguyên thủy. Nó thật đặc biệt
  • Bạn cần rất nhiều phương pháp khung

Con trăn

Python là rất nhiều 'tinh khiết'. Không có loại nguyên thủy. Một constructor không tồn tại, chỉ có một phương thức đặc biệt được gọi lúc khởi tạo.

Bạn không cần phải tương tác với bảng điều khiển, như bạn có REPL. Bạn chỉ có thể chơi trò chơi bằng cách sử dụng g.guess(35)và trả về một chuỗi.

Điều này làm cho ngôn ngữ dễ học hơn và nắm bắt các khái niệm OOP cơ bản.


0

Ý tưởng cốt lõi trong OOP là đóng gói (có nghĩa là gói hoặc ẩn) các biến và phương thức cùng nhau bên trong các lớp (mà python hoàn toàn hỗ trợ). Đó là về thiết kế mã của bạn xung quanh Danh từ. Sau đó, nó đi từ đó.

Mặc dù có sự khác biệt về triển khai (ví dụ: python không hỗ trợ khả năng hiển thị theo cách của Java) và sự khác biệt về cú pháp (trong Javascript, bạn phải tự kế thừa các phương thức), thiết kế cơ bản vẫn giữ nguyên.

Tuy nhiên, tôi nghĩ việc học OOP bằng một ngôn ngữ như Java dễ dàng hơn, bởi vì ngôn ngữ này đòi hỏi nó và cộng đồng ít đối nghịch với nó hơn là, cộng đồng python.

Nhưng có rất nhiều bài viết về thiết kế và thực hành OOP ngoài kia, và đọc nó không lãng phí công sức. Ngay cả khi tôi viết python (rất nhiều), tôi viết rất nhiều đối tượng và tôi sử dụng rất nhiều đối tượng từ các thư viện của bên thứ ba.


Ý tưởng mã là thông điệp đi qua. Cũng không có nguồn.
Người dùng

1
OOP không phải là về các lớp học.
Jörg W Mittag

1
@User Ý tưởng ban đầu của Alan Kay là về nhắn tin, nhưng kể từ đó, việc thực hành OO đã phát triển thành thiết kế theo danh từ hoặc các lớp đối tượng. Ví dụ, Tiến sĩ Kay cũng đã cho rằng Java không phải là Hướng đối tượng, vì nó không hỗ trợ ràng buộc muộn. @ Jorg lol ya ya
Cướp

0

Khi bạn học OOP bằng ngôn ngữ, bạn bắt đầu nghĩ bằng ngôn ngữ này. Ngôn ngữ ảnh hưởng đến những gì bạn nghĩ có thể được thực hiện và làm thế nào và cũng thêm một hương vị cho OOP.

  • Có nên có một Bộ sưu tập rác?
  • Tôi có thể thêm phương thức vào số nguyên không?
  • Tôi có sử dụng các lớp hoặc nguyên mẫu không?
  • Làm thế nào để các đối tượng phản ánh về chính họ?

Một số người không thể làm OOP mà không có lớp học. Một số phải giết đối tượng của họ với quá trình.

Có một cốt lõi của OOP và những ý tưởng ban đầu về nó. Bạn cũng có thể có một cái nhìn tại Smalltalk, Self, Simula, LISP, Drameak. Và cũng xem xét các loại ngôn ngữ không phải OOP như bash ngôn ngữ dataflow, APL, J. Những ngôn ngữ hợp lý Prolog. Haskell (loại lớp). Tất cả họ sẽ dạy cho bạn một suy nghĩ khác và bạn có thể học được rằng

  • OOP không phải là về ngôn ngữ bắt buộc
  • OOP không phải là về các lớp học

Và cuối cùng bạn có thể thấy OOP tốt cho cái gì. Ít nhất bạn sẽ có một ý tưởng khác về nó. Tôi đề nghị tìm cuộc nói chuyện của Alan Kay .


Nếu bạn không nhìn vào các ngôn ngữ thì bài viết này là vô ích.

Như bạn có thể thấy ở đây: Chúng tôi không thể đồng ý về OOP là gì.

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.