Thursday, December 31, 2009

Các khái niệm lập trình hướng đối tượng OOP

Một đối tượng là gì?

Java được biết đến như một ngôn ngữ hướng đối tượng (OO - object-oriented), bạn có thể sử dụng ngôn ngữ này để lập trình hướng đối tượng. Điều này rất khác so với lập trình thủ tục, và có thể hơi lạ lùng đối với hầu hết các lập trình viên không hướng đối tượng. Bước đầu tiên bạn phải hiểu đối tượng là gì, vì đó là khái niệm cơ sở của OOP.

Một đối tượng là một bó mã lệnh tự thân trọn vẹn (self-contained), tự hiểu chính mình và có thể nói cho các đối tượng khác về chính mình nếu chúng đưa ra các yêu cầu mà nó hiểu được. Một đối tượng có các thành phần dữ liệu (các biến) và các phương thức, chính là những yêu cầu mà nó biết cách trả lời (dù chúng không được diễn đạt bằng lời như các câu hỏi). Tập các phương thức mà một đối tượng biết cách trả lời được gọi là giao diện của đối tượng. Một vài phương thức là mở công cộng, nghĩa là các đối tượng khác có thể gọi đến chúng. Tập các phương thức này được gọi là giao diện công cộng của đối tượng.

Khi một đối tượng gọi phương thức của một đối tượng khác, thì được gọi là gửi một thông điệp (sending a message hoặc message send). Cụm từ này là thuật ngữ của OO nhưng hầu hết trong giới Java mọi người hay nói, “gọi phương thức này” hơn là “gửi thông điệp này”. Trong phần tiếp theo, chúng ta sẽ xem xét một ví dụ minh họa khái niệm giúp bạn hiểu vấn đề này rõ ràng hơn.

Ví dụ minh họa khái niệm đối tượng

Giả sử chúng ta có đối tượng Person. Mỗi Person có tên, tuổi, chủng tộc và giới tính. Mỗi Person cũng biết nói và biết đi. Một Person có thể hỏi tuổi của một Person khác, hoặc yêu cầu một Person khác bắt đầu đi (hay dừng). Diễn đạt theo thuật ngữ lập trình, bạn có thể tạo một đối tượng Person và khai báo một số biến (như tên và tuổi). Nếu bạn tạo một đối tượng Person thứ hai, đối tượng này có thể hỏi tuổi của đối tượng thứ nhất hoặc yêu cầu đối tượng thứ nhất bắt đầu đi. Nó có thể thực hiện những điều ấy bằng cách gọi đến các phương thức của đối tượng Person đầu tiên. Khi chúng ta bắt đầu viết mã lệnh bằng ngôn ngữ Java, bạn sẽ hiểu ngôn ngữ này triển khai thực hiện khái niệm đối tượng ra sao.

Nói chung, khái niệm đối tượng là như nhau trong ngôn ngữ Java và các ngôn ngữ hướng đối tượng khác, mặc dù việc triển khai thực hiện là khác nhau giữa các ngôn ngữ. Các khái niệm là phổ quát. Vì sự thật này, lập trình viên hướng đối tượng, bất chấp họ lập trình bằng ngôn ngữ nào, có xu hướng phát biểu khác so với những lập trình viên thủ tục. Các lập trình viên thủ tục thường nói về các hàm và các mô đun. Lập trình viên hướng đối tượng lại nói về các đối tượng và họ thường nói về các đối tượng này bằng cách sử dụng các đại từ nhân xưng. Chẳng hề bất thường khi bạn nghe một lập trình viên hướng đối tượng nói với đồng nghiệp, “đối tượng Supervisor nói với đối tượng Employee, ‘cho tôi ID của cậu,’” vì anh ta cần những thứ này để gán nhiệm vụ cho Employee.

Lập trình viên hướng thủ tục có thể nghĩ cách nói chuyện này thật lạ lùng, nhưng nó lại hoàn toàn bình thường đối với lập trình viên hướng đối tượng. Trong thế giới lập trình của họ, mọi thứ đều là đối tượng (cũng có một vài ngoại lệ đáng chú ý trong ngôn ngữ Java) và các chương trình là chỉ là sự tương tác (hay nói chuyện) giữa các đối tượng với nhau.

Các nguyên tắc hướng đối tượng cơ bản

Khái niệm đối tượng là trọng yếu đối với lập trình hướng đối tượng, và dĩ nhiên, ý tưởng các đối tượng giao tiếp với nhau bằng các thông điệp cũng vậy. Nhưng có 3 nguyên tắc cơ bản mà bạn cần hiểu.

Bạn có thể nhớ 3 nguyên tắc hướng đối tượng cơ bản bằng cụm viết tắt PIE:

  • Đa hình ( Polymorphism)
  • Thừa kế ( Inheritance)
  • Bao gói ( Encapsulation)

Đó là những từ trừu tượng nhưng những khái niệm này thực sự không quá khó hiểu. Trong các phần tiếp theo, chúng ta sẽ bàn về từng khái niệm này ở mức độ chi tiết hơn, theo thứ tự ngược lại.


Bao gói

Hãy nhớ rằng, một đối tượng là tự thân trọn vẹn, chứa đựng các thành phần dữ liệu và hành động mà nó có thể thực hiện trên các thành phần dữ liệu ấy. Đây là việc triển khai thực hiện nguyên lý gọi là ẩn giấu thông tin. Ý tưởng của nó là một đối tượng tự nó hiểu mình. Nếu một đối tượng khác muốn điều gì từ đối tượng này thì nó phải hỏi. Theo thuật ngữ lập trình hướng đối tượng, phải gửi một thông điệp đến một đối tượng khác để hỏi về tuổi. Theo thuật ngữ Java, phải gọi một phương thức của đối tượng khác để nó trả lại kết quả là tuổi.

Sự bao gói đảm bảo rằng mỗi đối tượng là khác nhau và chương trình là một cuộc chuyện trò giữa các đối tượng. Ngôn ngữ Java cho phép các lập trình viên vi phạm nguyên lý này nhưng hầu như luôn là một ý tưởng tồi nếu làm như thế.

Thừa kế

Khi bạn được sinh ra, nói về khía cạnh sinh học, bạn là tổ hợp DNA của cha mẹ mình. Bạn không hoàn toàn giống ai trong số họ, mà bạn giống cả hai người. OO cũng có nguyên tắc tương tự đối với các đối tượng. Quay lại với đối tượng Person. Ta nhớ lại rằng mỗi người có một chủng tộc. Không phải tất cả các Person đều cùng chủng tộc, nhưng dù sao thì họ cũng có điểm tương tự như nhau chứ? Chắc chắn vậy! Họ chẳng phải ngựa, tinh tinh hay cá voi mà là người. Mọi con người đều có những điểm chung nhất định và điều này giúp phân biệt con người với các loài động vật khác. Nhưng giữa mọi người cũng có khác biệt với nhau. Một đứa trẻ có giống hệt một người trưởng thành không? Không. Đi lại và nói là khác nhau rồi. Nhưng một đứa trẻ thì vẫn chắc chắn là một con người.

Theo ngôn ngữ hướng đối tượng, Person và Baby là các lớp sự vật hiện tượng thuộc cùng một hệ thống phân bậc, và Baby thừa kế các đặc tính và hành vi từ lớp cha của nó. Chúng ta có thể nói rằng một Baby cụ thể là một kiểu Person hay Baby thừa kế từ Person. Nhưng không có chiều ngược lại – một Person không nhất thiết phải là một Baby. Mỗi đối tượng Baby là một cá thể của lớp Baby và khi chúng ta tạo một đối tượng Baby, chúng ta cá thể hóa lớp này. Hãy coi lớp như là khuôn mẫu chung cho các cá thể của lớp đó. Nói chung, đối tượng có thể làm những gì tùy thuộc vào kiểu của đối tượng đó là gì – hoặc nói theo cách khác, đối tượng đó là cá thể của lớp nào. Cả Baby và Adult đều thuộc kiểu Person, nhưng một đối tượng (Adult) có thể có một việc làm (job) còn đối tượng kia (Baby) thì không.

Theo thuật ngữ Java, Person là một lớp bậc trên (superclass) của Baby và Adult, và các lớp này là lớp con của Person. Một khái niệm có liên quan khác là ý tưởng về trừu tượng hóa. Person có mức trừu tượng hóa cao hơn Baby hay Adult. Cả hai đều là kiểu Person nhưng có những khác biệt nho nhỏ. Tất cả các đối tượng Person đều có những điểm chung (như tên và tuổi). Bạn có thể cá thể hóa một Person? Thực sự là không! Bạn hoặc có một Baby hoặc có một Adult. Trong Java, Person được gọi là lớp trừu tượng. Bạn không thể trực tiếp có một cá thể của lớp Person. Bạn sẽ có Baby hoặc Adult, cả hai đều là kiểu Person, nhưng là Person đã được thực tế hóa. Các lớp trừu tượng nằm ngoài phạm vi của tài liệu này, chúng tôi sẽ không nói thêm về chúng nữa.

Bây giờ, ta hãy suy nghĩ xem với một Baby, “nói” (speak) có nghĩa là gì. Chúng ta sẽ xét đến các hệ quả trong phần thảo luận tiếp theo.

Đa hình

Baby có “nói” như Adult không? Dĩ nhiên là không rồi. Một Baby có thể ê a, nhưng không nhất thiết nói ra những lời hiểu được như Adult. Do đó, nếu tôi cá thể hóa một đối tượng Baby (hay là “cá thể hóa một Baby” cũng có cùng ý nghhĩa – từ “đối tượng” được ngầm hiểu) và cho nó nói, thì nó chỉ có nghĩa là những tiếng ê a. Ta hy vọng rằng Adult “nói” thì mạch lạc hơn.

Trong hệ thống phân bậc con người, chúng ta có Person nằm ở đỉnh với Baby và Adult nằm phía dưới nó, là các lớp con. Tất cả mọi người đều có thể nói, Baby và Adult cũng vậy, nhưng sẽ nói khác nhau. Baby chỉ ê a và phát những âm thanh đơn giản. Adult nói thành lời. Đó chính là sự đa hình: các đối tượng làm việc theo cách riêng của chúng.

Ngôn ngữ Java là (và không là) OO ở chỗ nào?

Như chúng ta sẽ thấy, ngôn ngữ Java cho phép bạn tạo các đối tượng hạng nhất (first-class), nhưng không phải bất cứ cái gì trong ngôn ngữ này đều là đối tượng. Một số ngôn ngữ OO như Smalltalk lại hoàn toàn khác. Smalltalk hoàn toàn là OO, có nghĩa là mọi thứ trong ngôn ngữ này đều là đối tượng. Java là ngôn ngữ lai tạp giữa đối tượng và phi đối tượng. Nó cho phép một đối tượng biết rõ các đối tượng khác, nếu với tư cách là một lập trình viên bạn cho phép điều đó xảy ra. Điều này vi phạm nguyên lý bao gói.

Tuy nhiên, ngôn ngữ Java cũng cung cấp cho tất cả các lập trình viên OO những công cụ cần thiết để tuân theo mọi quy tắc OO và viết mã lệnh OO rất chuẩn. Nhưng làm được như vậy cần phải tự có kỷ luật. Ngôn ngữ không ép bạn làm việc đúng đắn được.

Trong khi những người thuần túy chủ nghĩa hướng đối tượng tranh luận xem liệu Java là hướng đối tượng hay không, thực sự đây không phải là một lý lẽ mang lại ích lợi. Nền tảng Java sẽ giữ vững vị trí của nó. Hãy học cách lập trình hướng đối tượng tốt nhất có thể với mã lệnh Java và cứ để những lý lẽ thuần túy chủ nghĩa cho những người khác. Ngôn ngữ Java giúp bạn viết chương trình rõ ràng, khá ngắn gọn, dễ bảo trì, điều này là khá đủ trong cuốn sách của tôi đối với hầu hết các tình huống nghề nghiệp.

1 comment:

  1. Welcome to Situs Judi Slot Online & Agen Judi Online
    JTGames 춘천 출장샵 merupakan situs 사천 출장마사지 judi slot online dan 남양주 출장안마 agen judi online terpercaya 나주 출장안마 di Indonesia. Main 목포 출장샵 game dan dapatkan jackpot terbesar Join.

    ReplyDelete