Nên chọn ngôn ngữ nào để học OOP

Em đã học cơ bản của C và C++ . Giờ em muốn học đến hướng đối tượng em nên chọn ngôn ngữ nào để học. Mong mọi người giúp em, cảm ơn mọi người!

C++ cũng có OOP nhưng mà theo mình thì nên chọn Java vì nó khá nổi tiếng về OOP :smile:

2 Likes

C++ là tốt nhất để học OOP nếu đc.
Polymorphism trong C++ được thể hiện rõ nhất với việc phải liên tục overload các hàm. Chưa kể đến template class. Nếu rành OOP trong C++ thì chuyển sang Java và C# rất dễ.

  1. Tại sao lại phải overload các hàm?
  2. Đặc trưng của OOP là override chứ đâu phải overload? Còn nếu lúc nào cũng phải override thì nó không còn là kế thừa nữa.
  3. Nếu rành OOP trong C# thì chuyển sang C++ hay Java cũng dễ mà. Mình học OOP chứ có phải học cú pháp đâu? Cú pháp không biết thì tra Google, chứ tư tưởng và thuật toán thì phải luyện tập, mà luyện tập bằng C++ khó lắm, vì nó nửa mùa :smile:
2 Likes

C++ nửa mùa chỗ nào? Hầu hết các software lớn và tính toán nặng đều viết bằng C++.
Trong C++ các khái niệm như abstract, virtual, interface và delegate khác với C# và Java nhiều, bởi vì nó liên quan đến nhiều đến con trỏ và implementation cũng khác.
Nếu thích học OOP hiểu đc sâu nhất thì phải qua C++. Còn không bất cứ ngôn ngữ high level nào cũng có thể học và áp dụng OOP.

1 Like

nửa mùa chắc ở chỗ lúc nào cũng phải thêm cái virtual:joy: Trong khi OOP mà ko có polymorphism thì đâu phải OOP, tự dưng bắt mỗi lần xài lại phải thêm virtual vào. Với lại tự dưng phải có virtual dtor, ko thì chết :joy:, tức là phải biết về quản lý bộ nhớ, chả liên quan tới OOP. Rồi thì object lúc nào trên stack lúc nằm trên heap, pass reference hay pass con trỏ, rồi con trỏ thông minh này nọ quá sa đà vào quản lý bộ nhớ.

vì lý do reference ra đời quá chậm nên this là con trỏ mà ko phải là reference, trong khi tính chất ,của this là reference: ko gán lại được, ko có giá trị null. Nỗi cái this-> chứ ko phải this. là thấy faillll rồi :joy: :joy:

hay nói 2 mùa mới đúng chứ ko phải nửa mùa, ở đâu lòi ra mấy cái như multiple inheritance gì đó y như ăn tôm chưa bóc vỏ, nhiệm vụ bóc vỏ là của ltv C++, trong khi Java nó thuần OOP nó bóc vỏ bỏ mấy cái vớ va vớ vẩn đó, ltv chỉ việc ăn thôi :joy:

3 Likes

Nói về OOP, người ta thường nói về Java và C#. Nhưng mình thấy nếu học để hiểu OOP thì nên chọn Java, vì nó hầu như không có gì ngoài OOP :joy:. Chứ các ngôn ngữ về sau cái gì cũng hỗ trợ tận răng, code ngắn nhưng mà che giấu bản chất.

C++ người ta dùng nhiều vì nó nhanh chứ đâu phải vì OOP nó sáng sủa. Các khái niệm nó khác với C# và Java vì nó còn đang sơ khai, người ta xây dựng OOP trong C++ để nó làm việc được, chứ chưa làm việc hiệu quả. Chính Java được thiết kế lại mới trở thành chuẩn mực của OOP về sau.

Điểm khác biệt của C++ là sau khi học các ngôn ngữ bậc cao một thời gian, bạn mà học thêm C++ thì phải học về truyền con trỏ hay truyền biến, cấp phát - thu hồi nó hơi phức tạp tí thôi.

5 Likes

Đặc trưng của Polymorphism là cả overload và override. Trong c++ kiểu gì cũng sẽ gặp operator overload trước khi gặp khái niệm override. Bạn nên xem lại khái niệm Polymorphism

Ở runtime, để mà compiler biết được class, method nào để gọi đúng nếu như xài inheritance thì nó phải dùng khái niệm Virtual table. Nếu ko có virtual table thì ko sử dụng được inheritance, 1 trong 3 khái niệm chính của OOP

Ở Java các method đều được gắn virtual ẩn mặc dù bạn không phải type ra. C++ bắt buộc phải type ra. Đó cũng là lý do tại sao phải có dtor trong C++ thay vì nó được garbage collector sử lý trong C# và Java.

Nếu muốn xài this. trong c++ thì hàm phải gắn Refreturn *this. Còn muốn xài this -> thì hàm phải gắn Pointerreturn this.

Không hiểu sao mà câu này phát biểu được. C++ là một trong những ngôn ngữ lâu đời nhất trước cả Java mà không phải là proprietary, chính vì vậy nó luôn được nâng cấp bởi nhiều hội đồng C++ trên nhiều nước khác nhau (thay vì Java và C# thuộc về Sun và Microsoft)

C++ không hiệu quả thì lấy đâu ra mà tốc độ nhanh? Tại sao cryptocurrency như Bitcoin được thiết kế trên c++ ?

Chính vì tính năng nhanh của nó lên nó sẽ có bất lợi là có nhiều khái niệm khó lại hay dễ sinh ra lỗi nhỏ, không thích hợp với những software không đặt nặng yếu tố tốc độ.

Như mình đã nói, vì bạn thớt đã có nền tảng c++ thì học OOP trong c++ là sẽ hiểu được thật sự tại sao OOP hoạt động như thế nào và cách tối ưu hóa nó. Còn nếu chưa học 1 ngôn ngữ lập trình nào thì C# và Java sẽ nhanh hơn để nắm bắt khái niệm OOP vì nó abstract những khái niệm khó ở background.

2 Likes

đang nói tới C++ ko phải thuần OOP mà. Tại sao virtual method lại cần keyword virtual, trong khi hầu như xài OOP là phải override method, tức là phải xài virtual method, mà mỗi lần xài lại mất công thêm keyword virtual vào, so với C# Java ko cần. Cú pháp ko giống ai như vậy là nửa mùa :kissing:

virtual dtor là cái ko liên quan tới OOP. OOP cần gì phải biết tới mem leak là cái gì? Viết OOP trong C++ vô tình phải viết thêm hàm dọn rác. Rất xao nhãng, rất nửa mùa :kissing_closed_eyes:

ko ai nói tới tốc độ C++ nhanh hay chậm ở đây cả. Đem OOP nói trước mặt cái lão làng C++ mà bảo nó “nhanh” thì coi chừng bị trợn mắt :joy: Mấy lão làng rất ghét OOP và virtual calls vì nó được coi là “chậm” trong C++. Khi đã xác định số lượng class là bao nhiêu rồi thì dù nó có là 100 class con đi nữa thì vẫn có thể xài template thay thế đa hình, đâu cần đụng tới OOP.

còn this là con trỏ nữa. Thay vì viết:

bool compare(const Object& that)
{
    return this.value < that.value;
}

phải viết là

bool compare(const Object& that)
{
    return this->value < that.value;
    //hoặc return value < that.value;
}

rất xấu, rất quê mùa :smiling_imp:

1 Like

Đau đầu với bạn quá, bạn gặp operator overload thì liên quan gì đến OOP? Bạn đừng nghĩ trong C++ có overload thì các ngôn ngữ khác không có, đơn giản là đối với OOP nó là chức năng thừa. Nếu bạn muốn overload thì C# cũng có nhưng mình không recommend C#, vì nó không phải là đặc trưng của OOP. Còn method overload thì trong các ngôn ngữ mình từng sử dụng có mỗi JavaScript là không có, nhưng đó cũng không phải là đặc trưng của OOP luôn, bạn kể ra để làm gì?

Bạn có vấn đề đọc hiểu không vậy? Mình bảo làm việc với C++ không hiệu quả, người ta thiết kế lại trong các ngôn ngữ sau này để làm việc hiệu quả hơn thì liên quan gì đến sản phẩm chạy nhanh hay chậm? Với cả nếu đã muốn sản phẩm chạy nhanh, sao bạn lại còn chọn OOP?

Trong khi bạn đang nghĩ ngợi rất cao siêu theo kiểu như “Bọn Java, C#, Python… là bọn cùi bắp, app làm thì nhanh mà chạy thì chậm”, người ta vẫn tiếp tục sử dụng chúng, vì nhanh chậm phụ thuộc nhiều vào trình độ của người lập trình hơn là ngôn ngữ. Đến cả máy chủ của Microsoft phục vụ hàng chục nghìn người dùng cùng lúc vẫn có thể sử dụng .NET được thì không mắc cớ gì bạn chủ thớt phải học một thứ OOP nửa mùa, không biết bao giờ mới có thể viết được một sản phẩm tốt như khi bạn ấy học Java trong cùng thời gian.

Overload mà không phải đặc trưng của OOP vậy bạn cho mình biết Polymorphism là nghĩa như thế nào được không ? Polymorphisim cho phép 1 hàm cùng 1 tên giống nhau nhận vào variable khác nhau.

void Foo(int i)
 
void Foo(string s)

Đó chính là khái niệm chủ đạo của OOP ah ? Bất cứ ngôn ngữ nào cũng cho phép overload từ constructor cho đến operator, method.

Hello,

Mình giả định là bạn mới bắt đầu lập trình (như bạn nói: cơ bản về C/C++) và đang muốn bắt đầu học về lập trình hướng đối tượng. Mình giả định là bạn đã biết lập trình hướng đối tượng là 1 paradigm (mô hình/dạng mẫu) trong một số dạng mẫu khác: Procedure Programming (Lập trình thủ tục), Functional Programming (lập trình hàm), Logic, Data-driven Programming,… và rất nhiều paradigms khác[1]. Và vì nó là một mô hình, nên các ngôn ngữ có thể áp dụng OOP vào như một tính năng, vậy nên mới có một số ngôn ngữ multi-paradigm: một ngôn ngữ hỗ trợ nhiều paradigms[2]. Fun fact: bạn có thể viết OOP trên C [3]. Quay lại câu hỏi chính của bạn, mình nghĩ điều đó phụ thuộc vào chính định hướng sau này của bạn nữa.

  1. Nếu bạn muốn học OOP một cách hàn lâm, học để hiểu bản chất, mình khuyên chọn Java. Bởi vì: (1) Cấu trúc Java ít thay đổi, điều đó làm các code Java xuất hiện từ cách đây 10-15 năm vẫn có thể chạy trên JVM ngày nay, và theo mình đó là lý do mà cách sách viết về lập trình thường dùng Java như một ngôn ngữ viết prototype, (2) cộng đồng Java rất đông, rất nhiều lập trình viên có trình độ cao. (3) bản chất của Java là WORA nên rất nhiều lĩnh vực có thể áp dụng được, do đó tỷ lệ tìm được việc làm sau này cao hơn. Do đó Java nằm trong top đầu.
  2. C++, cái này là on your favor, bạn muốn hiểu hơn về hệ thống, quản lý bộ nhớ, hướng đi sau này của bạn quan trọng ở tốc độ xử lý phải nhanh và bạn muốn học cái gì gần gũi với những cái gì bạn đã học. Cộng đồng C++ mình nghĩ không nhiều bằng Java (any source?) nhưng về trình độ thì đa phần ai trụ được trong ngành đều rất giỏi, hiểu rất sâu.
  3. PHP/Python: Vì 2 ngôn ngữ này không nằm trong list của bạn nên mình đưa vào top 3 mặc dù mình rất yêu thích Python. Python đơn giản, dễ hiểu, hỗ trợ multi-paradigm, cộng đồng cực mạnh, phát triển trên nhiều lĩnh vực,… mình thấy Python là ngôn ngữ đơn giản NHẤT để bắt đầu học lập trình nói chung. PHP cũng tương tự nhưng gần giống với Java hơn (any comment?) về cú pháp, độ dài dòng/cụ thể (verbosity), cộng đồng cũng rất lớn, mặc dù mình cảm nhận tỷ lệ lập trình viên có trình độ cao / tổng số lập trình viên PHP không thể bằng Java.
    … your list goes on.

Và mình cũng có 1 list những ngôn ngữ KHÔNG nên học khi mới bắt đầu OOP:

  1. Javascript: Mặc dù nhiều người nói ES6 đơn giản hóa việc lập trình Javascript nhưng có cả tỷ codebase cũ viết trên Javascript khiến người mới học điên đầu.
  2. C#/Objective-C: Nếu bạn chỉ gắn bó với Windows thì bạn có thể bỏ qua phần này. .Net trên Linux là khá rủi ro nếu đó là lựa chọn lâu dài của bạn. [4] Objective-C đang đi xuống, Apple cũng tập trung nhiều hơn vào Swift hơn là Obj-C. [5]
  3. Ruby: Ruby đang trên đường đi xuống, 1 phần cũng là những đối thủ cạnh tranh trong lĩnh vực Web development đuổi kịp.

[1] https://en.wikipedia.org/wiki/Programming_paradigm
[2] https://en.wikipedia.org/wiki/Comparison_of_multi-paradigm_programming_languages
[3] https://stackoverflow.com/questions/351733/can-you-write-object-oriented-code-in-c
[4] https://dubst3pp4.github.io/post/2018-01-03-csharp-on-linux/
[5] https://www.quora.com/Why-did-Apple-abandon-Objective-C-and-invest-so-much-into-Swift-and-its-development-Is-Android-following-suit-with-Kotlin

Edit 1: rephrases
Edit 2: Add Objective-C

2 Likes

tại sao lại ko nên học C# khi mới bắt đầu OOP chỉ vì Linux ko xài C# được? :V

edit: tại sao lại học Python khi mới bắt đầu OOP vì Python hỗ trợ multi-paradigm? :no_mouth: Nhìn anh Python OOP ko có private protected gì hết thấy đao lòng quá

Điểm quan trọng nhất của Polymorphism đó là đối với mỗi đối tượng khác nhau, cùng một hàm sẽ thực hiện các nhiệm vụ khác nhau. Ví dụ X và Y đều là lớp con của A, nhưng phương thức xuat() thì được override lại. Nếu ta có một mảng kiểu A[] lẫn lộn các đối tượng kiểu X và Y, ta sẽ thu được kết quả rất khác nhau mặc dù chỉ gọi 1 hàm:

foreach (A a in array)
	a.xuat();

Còn nạp chồng phương thức, nó chẳng phải cái đáng quan tâm của Tính đa hình, đơn giản vì bản chất nó là khai báo một phương thức khác rồi. Chỉ đơn giản là khai báo một phương thức cùng tên và bạn gọi nó là Tính đa hình trong khi muốn nó chạy phải nhập chính xác tham số??? C không có nạp chồng trong khi C++ có không có nghĩa là nạp chồng toán tử / nạp chồng phương thức là đặc trưng của OOP bạn nhé.

À mà quên mất, như mình nói ở trên, JavaScript nay đã có OOP nhưng vẫn không có function overload :joy: Không thể nói là bất cứ ngôn ngữ nào được. Còn operator overload thì hầu hết các ngôn ngữ hiện được sử dụng nhiều đều không hỗ trợ.

Hoặc nếu bạn muốn tìm hiểu kỹ hơn, thay vì search “Polymorphism” chung chung, bạn có thể search “Polymorphism in OOP” và xem kết quả.

overload cũng là đặc trưng của đa hình mà :V 1 hàm có thể thực hiện nhiều việc khác nhau là đa hình. fun(1) và fun(“hi”) cho ra kết quả khác nhau nghĩa là hàm fun là đa hình. Đâu nhất thiết phải có object mới có đa hình.

1 Like
  1. Nếu công việc của bạn ý nằm trong ecosystem của Windows thì C# không nằm trong mục không nên bắt đầu. Mình cũng có nói rồi mà.
  2. Mình thậm chí nói Python là ngôn ngữ nên học khi bắt đầu học lập trình nói chung chứ không riêng gì khi học OOP, dĩ nhiên là nhận định cá nhân thôi, vì tính đơn giản, dễ đọc, dễ đọc, dễ hiểu và tạo hứng thú khi học của nó chứ không chỉ là vì nó hỗ trợ multi-paradigm.

Vậy là bạn lại đem cách tư duy của ngôn ngữ khác vào với Python rồi. Đúng như bạn nói, không một attribute nào trong Python thực sự là non-public, thay vào đó là convention [1] giúp lập trình viên chọn biến nào là public (normal) hay non-public ( with leading underscore _ ) và những lập trình viên sau này đọc lại code hiểu. Điều này ép lập trình viên phải thận trọng hơn, suy nghĩ nhiều hơn trong quá trình xây dựng app.

[1] https://www.python.org/dev/peps/pep-0008/#designing-for-inheritance

các NNLT OOP thông dụng khác đều có public/protected/private, tự dưng Python lại ko có, OOP nửa mùa còn hơn C++ nữa :V Thêm __ vô trước tên biến là các ltv phải tự biến tấu để có cái tính năng giấu data này, ông Python kêu ko cần giấu data nhưng thực tế lại rất cần :V

câu hỏi là ngôn ngữ nào để học OOP mà ông xếp Python lên trên C# thì kì quá. Thay vì xếp C# ở list ko nên sao ko quẳng nó lên list “có” nên, thay vì nói nếu chỉ lập trình trên Windows sao ko nói chưa lập trình trên Linux, dìm hàng C# quá trong khi nó là “clone” Java nổi tiếng về OOP.

OOP thì cứ Java và C# mà phang thôi. Vì sao á ? Vì nó nhiều tài liệu :v:, mỗi nơi viết mỗi kiểu đọc nhiều là nó tự thấm. M chưa bao giờ đụng C++ OOP nhưng mà thấy cãi nhau thế này tức là nó phức tạp rồi bạn, học 1 cái mới mà đụng ngay đến cái phức tạp thì nãn lắm :smiley:.

Bạn có thể cho mình ví dụ use-case cụ thể trong việc C#/Java hay C++ có private/protect/public để giải quyết 1 công việc mà Python không thể giải quyết không? Mình làm việc với Python mà chưa bao giờ gặp phải vấn đề này cả.

Theo mình hiểu, Method Visibility hay Access Modifiers không ảnh hưởng tới tới cách thức thực thì mà chỉ ảnh hưởng tới cách thức mà method/variable đó được gọi[1].

Việc không cho C# vào danh sách không phải mình đánh giá thấp C#, chỉ là xét trên mối tương quan giữa nền tảng mà bạn ấy có thể hướng tới. Với mình không có cái gọi là bảng xếp hạng ngôn ngữ nào trên ngôn ngữ nào, chỉ là việc “using right tools for the right job”, và vì Python là ngôn ngữ mà mình thấy đơn giản, phù hợp cho người mới học lập trình nhất chứ mình không nói đến nó hỗ trợ lập trình OOP tốt hơn hay kém hơn những ngôn ngữ khác.

Mình thấy các bạn tranh luận về việc OOP phải thế này, OOP phải thế khác, Polymorphism phải như vậy, phải như kia, hay ngôn ngữ này hỗ trợ tốt cái này trong OOP hơn ngôn ngữ kia, do đó học ngôn ngữ này tốt hơn… Mình thấy suy nghĩ như vậy là chưa đúng, OOP được ưa chuộng là do nó gần gũi với cách thức tư duy của con người nhất, nhưng suy cho cùng nó cũng chỉ là một mô hình, định hướng cho lập trình viên để giải quyết 1 bài toán cụ thể. Thậm chí, gần đây OOP nhận nhiều chỉ trích từ chính thiết kế của nó [2.3.4]

[1] https://stackoverflow.com/questions/643775/private-methods-and-properties-vs-public-ones-regarding-their-memory-footprints?lq=1
[2] http://www.oocities.org/tablizer/myths.htm
[3] https://medium.com/@cscalfani/goodbye-object-oriented-programming-a59cda4c0e53
[4] https://news.ycombinator.com/item?id=18381640
[5] bonus: Google keyword: banana-gorilla-jungle problem

cái pubic/private ko ảnh hưởng tới code chạy thế nào nhưng cú pháp viết ra rất mù mờ ko trong sáng. Python nó nửa nạc nửa mỡ, nửa OOP nửa hàm, ví dụ như tại sao method nào cũng phải có cái self ở trỏng, giống như code OOP kiểu C vậy. Ko ảnh hưởng gì nhưng viết rất là đau mắt mỏi tay. Bất tiện như vậy tại sao lại cho ưu tiên hơn C# :dizzy_face: À ngoài ra bản thân nó còn có vụ mixin gì đó rất kì lạ hay kì diệu :V Bản thân nó là script nên OOP trong Python khá lỏng lẻo ko giống OOP “truyền thống”. Mới học thì nên học cái truyền thống trước :V

ví dụ thế này:

class A:
    def print(self):
        print("A")
class B:
    def print(self):
        print("B")
class C:
    pass
        
p = [A(), B(), C()]
p[2].__dict__['print'] = lambda: print("C")
p[0].print()
p[1].print()
p[2].print()

cả 2 đều in ra được, A và B chả liên quan tới nhau, vậy cần gì tới đa hình nữa :V Thêm cái nữa nhìn 2 chữ “self” là thấy ngứa mắt rồi :joy: Thêm cái nữa 1 object lúc nào cũng thêm bớt tính năng vào được rất là dị hợm :V

2 Likes
83% thành viên diễn đàn không hỏi bài tập, còn bạn thì sao?