Khái Lược về Lập Trình Hướng Đối Tượng

Vietsciences-Võ Quang Nhân        20/11/2005

 

Các bạn thân mến,
Bài viết sau đây xin giới thiệu với các bạn mới làm quan với khoa học lập trình một khái niệm quan trọng.  Việc hiểu rõ triết lý bên trong của khái niệm này sẽ giúp các bạn học hỏi tìm hiểu là nhập cuộc được nhanh chóng hơn.  Bài viết này đã được trình bài trong khuôn khổ giấy phép GNU đặc biệt được tác giả khởi đăng trên http://vi.wikipedia.org  Do đó, các bạn có thể dùng bài viết này trong mọi mục đích riêng tư. Bài viết sau đây đã được lượt bớt những chi tiết không quan trọng về thêm vào nhiều chi tiết khác giúp cho việc hiểu rõ khái niệm. Yêu cầu tối thiểu của bài này là người đọc phải biết qua một ít từ vựng cơ bản về lập trình cũng như về khái niệm công nghệ lập trình. Nhiều thuật ngữ chuyên môn trong bài có thể tìm thấy trong từ điển bách khoa wikipedia nêu trên phần Anh ngữ (http://vi.wikipedia.org )

Chúc các bạn may mắn trong mùa thi cuối học kì năm 2005.

Võ Quang Nhân
 

1. Khái niệm:

Lập trình hướng đối tượng (gọi tắt là OOP, từ chữ Anh ngữ Object-Oriented Programming), hay còn gọi là lập trình định hướng đối tượng, là kĩ thuật lập trình hỗ trợ công nghệ đối tượng. OOP được xem là giúp tăng năng suất, đơn giản hóa độ phức tạp khi bảo trì cũng như mở rộng phần mềm bằng cách cho phép lập trình viên tập trung vào các đối tượng phần mềm ở bậc cao hơn. Ngoài ra, nhiều người còn cho rằng OOP dễ tiếp thu hơn cho những người mới học về lập trình hơn là các phương pháp trước đó.

Một cách giản lược, đây là một khái niệm và là một nỗ lực nhằm giảm nhẹ các thao tác viết mã cho người lập trình, cho phép họ tạo ra các chương trình ứng dụng mà các yếu tố bên ngoài có thể tương tác với các chương trình đó giống như là tương tác với các đối tượng vật lý.

Những đối tượng trong một ngôn ngữ OOP là các kết hợp giữa mã và dữ liệu mà chúng được nhìn nhận như là một đơn vị duy nhất. Mỗi đối tượng có một tên riêng biệt và tất cả các tham chiếu đến đối tượng đó được tiến hành qua tên của nó. Như vậy, mỗi đối tượng có khả năng nhận vào các thông báo, xử lý dữ liệu (bên trong của nó), và gửi ra hay trả lời đến các đối tượng khác hay đến môi trường.

2. Các tính chất cơ bản


2.1 Đối tượng

  • Đối tượng (object): Các dữ liệu và chỉ thị được kết hợp vào một đơn vị đầy đủ tạo nên một đối tượng. Đơn vị này tương đương với một chương trình con và vì thế các đối tượng sẽ được chia thành hai bộ phận chính: phần các phương pháp và phần các thuộc tính. Trong thực tế, các phương pháp của đối tượng là các hàm và các thuộc tính của nó là các biến, các tham số hay hằng nội tại của một đối tượng (hay nói cách khác tập hợp các dữ liệu nội tại tạo thành thuộc tính của đối tượng). Các phương pháp là phương tiện để sử dụng một đối tượng trong khi các thuộc tính sẽ mô tả đối tượng là cái gì.
    Các phương pháp và các thuộc tính thường gắn chặt với thực tế các đặc tính và sử dụng của một đối tượng.
    Trong thực tế, các đối tượng thường được trừu tượng hóa qua việc định nghĩa của các lớp (class).
    Tập hợp các giá trị hiện có của các thuộc tính tạo nên trạng thái nội tại (hay gọn hơn trạng thái) của một đối tượng.
    Mỗi phương pháp hay mỗi dữ liệu nội tại cùng với các tính chất được định nghĩa (bởi người lập trình) được xem là một đặc tính riêng của đối tượng. Nếu không có gì lầm lẫn thì tập hợp các đặc tính này gọi chung là đặc tính của đối tượng.
    Như vậy, một đối tượng nhờ vào các phương pháp mà nó có khả năng tưong tác (hay trao đổi, điu chỉnh và vận chuyển thông tin) với môi trường bên ngoài và với các đối tương khác các tính chất này gọi là các ứng xử (behave) của đối tương. Mặt khác vì  một đối tượng có chứa dữ liệu nội tại nên nó thể xem là một kiểu dữ liệu (data type) năng động.

2.2 Các tính chất chính:

  • Tính trừu tượng (abstraction): Đây là khả năng của chương trình bỏ qua hay không chú ý đến một số khía cạnh của thông tin mà nó đang trực tiếp làm việc lên, nghĩa là nó có khả năng tập trung vào những cốt lõi cần thiết. Mỗi đối tượng phục vụ như là một "động tử" có thể hoàn tất các công việc một cách nội bộ, báo cáo, thay đổi trạng thái của nó và liên lạc với các đối tượng khác mà không cần cho biết làm cách nào đối tượng tiến hành được các thao tác. Tính chất này thường được gọi là sự trừu tượng của dữ liệu.
    Tính trừu tượng còn thể hiện qua việc một đối tượng ban đầu có thể có một số đặc điểm chung cho nhiều đối tượng khác như là sự mở rộng của nó nhưng bản thân đối tượng ban đầu này có thể không có các biện pháp thi hành. Tính trừu tượng này thường được xác định trong khái niệm gọi là lớp trừu tượng hay hay lớp cơ sở trừu tượng.
  • Tính đóng (encapsulation): Tính chất này sẽ không cho phép người sử dụng các đối tượng thay đổi trạng thái nội tại của một đối tượng trong các chiều hướng không định trước được. Chỉ có các phương pháp nội tại của đối tượng cho phép thay đổi trạng thái của nó. Việc cho phép môi trường bên ngoài tác động lên các dữ liệu nội tại của một đối tượng theo kiểu cách nào là hoàn toàn tùy thuộc vào người viết mã. Đây là tính chất an toàn của một đối tượng.
  • Tính đa hình (polymorphism): Thể hiện thông qua việc gửi các thông báo. Việc gửi các thông báo này có thể so sánh như là việc gọi các hàm bên trong của một đối tượng. Các phương pháp dùng trả lời cho một thông báo sẽ tùy theo đối tượng mà thông báo đó được gửi tới sẽ có phản ứng khác nhau. Người lập trình có thể định nghĩa một đặc tính (chẳng hạn thông qua tên của các phương pháp) cho một loạt các đối tượng gần nhau nhưng khi thi hành thì dùng cùng một tên gọi mà sự thi hành của mỗi đối tượng sẽ tự động xảy ra tương ứng theo đặc tính của từng đối tượng mà không bị nhầm lẫn.
Thí dụ khi định nghĩa hai đối tượng "hinh_vuong" và "hinh_tron" thì có một phương pháp chung là "chu_vi". Khi gọi phương pháp này thì nếu đối tượng là "hinh_vuong" nó sẽ tính theo công thức khác với khi đối tượng là "hinh_tron".
  • Tính kế thừa (inheritance): Đặc tính này cho phép một đối tượng có thể có sẵn các đặc tính mà đối tượng khác có. Điều này cho phép các đối tượng chia sẻ hay mở rộng các đặc tính sẵn có cũng như các biểu hiện mà không phải tiến hành định nghĩa lại. Tuy nhiên, không phải ngôn ngữ định hướng đối tượng nào cũng có tính chất này.


3. OOP như là một điểm mới về mẫu hình lập trình

3.1 Mẫu hình lập trình:


3.1.1 Khái niệm Mẫu hình :


Mẫu hình  hay còn gọi là  mẫu hình khoa họcparadigm: Theo triết gia Thomas Kuhn (1922-1996) dùng để chỉ tập họp các thực hành và thao tác mà chúng xác định nên một khuôn khổ thực nghiệm khoa học trong suốt một giai đoạn của thời gian.. Sau đó, Kuhn lại định nghĩa mẫu hình như là:

  • Cái gì để được quan sát và nghiên cứu kỹ lưỡng. (đối tượng)
  • Các loại câu hỏi mà chúng cần được giả thiết và thử nghiệm (hay chứng minh) cho các câu trả lời trong quan hệ tới các chủ thể.
    • các câu hỏi đó được đặt ra như thế nào.
    • các kết qủa của sự điều tra nghiên cứu nên được diển giải như thế nào.
       

     

3.1.2. Trong khoa tin học

3.1.2.1 Ý nghĩa chung:

Trong tin học, một mẫu hình lập trình là một cách thức lập trình mà nó là kiểu có tính mẫu hình trong việc tiến hành công nghệ phần mềm.

Một mẫu hình lập trình cung cấp (và xác định) quan điểm mà người lập trình có về sự thực thi của chương trình. Thí dụ: trong lập trình hướng đối tượng, các lập trình viên có thể xem một chương trình như là một tập họp của các đối tượng có tính tương tác, trong khi đó, trong lập trình chức năng, nó là một chương trình có thể được xem như là một chuỗi các đánh giá của các hàm vô thức.

Các nhóm khác nhau trong công nghệ phần mềm đề xướng các phương pháp khác nhau, các ngôn ngữ lập trình khác nhau tức là các mẫu hình lập trình khác nhau. Một số ngôn ngữ được thiết kế để hỗ trợ một mẫu hình đặc thù (Java hỗ trợ lập trình hướng đối tượng trong khi Haskell hỗ trợ lập trình chức năng). Số ngôn ngữ khác lại hỗ trợ nhiều mẫu hình (như Python và Common Lisp).

Một số mẫu hình lập trình cấm các thao tác mà chính ngôn ngữ đó có. Chẳng hạn, lập trình cấu trúc không cho phép sử dụng lệnh goto.

Quan hệ giữa các mẫu hình lập trình và các ngôn ngữ lập trình có thể phức tạp vì một ngôn ngừ có thể hỗ trợ nhiều mẫu hình lập trình. Thí dụ như C++ được thiết kế để hỗ trợ các phần tử của lập trình thủ tục, lập trình hướng đối tượng và lập trình tiêu bản.

Mặc dù vậy, những người thiết kế và những người lập trình quyết định làm thế nào để xây dựng một chương trình dùng các phần tử của mẫu hình. Người ta có thể viết một chương trình hoàn toàn theo kiểu lập trình thủ tục trong C++, cũng có thể viết chương trình hoàn toàn hướng đối tượng, hay viết chương trình có các phần tử của cả hai mẫu hình.

3.1.2.2 Một số thí dụ về mẫu hình trong tin học

  • Lập trình cấu trúc- so sánh với Lập trình không cấu trúc (unstructured programming)
  • Lập trình mệnh lệnh (imperative programming), so sánh với Lập trình khai báo (declarative programming)
  • Lập trình truyền báo (message passing programming), so sánh với Lập trình cưỡng bách (imperative programming)
  • Lập trình thủ tục (procedural programming), so sánh với Lập trình chức năng (functional programming)
  • Lập trình bậc giá trị (value-level programming), so sánh với Lập trình bậc chức năng (function-level programming)
  • Lập trình điều khiển theo mạch (flow-driven programming), so sánh với Lập trình điều khiển theo sự kiện (event-driven programming)
  • Lập trình vô hướng (scalar programming), so sánh với Lập trình mảng (array programming)
  • Lập trình cưỡng chế (constraint programming), so sánh với Lập trình Lô gíc (logic programming)
  • Lập trình định hướng thành phần (component-oriented programming) (như OLE)
  • Lập trình định dạng (aspect-oriented programming) (như AspectJ)
  • Lập trình kí hiệu (symbolic programming) (như Mathematica)
  • Lập trình định hướng bảng (table-oriented programming) (như FoxPro của Microsoft)
  • Lập trình ống (pipeline programming) (như dòng lệnh UNIX)
  • Lập trình hậu đối tương (post-object programming)
  • Lập trình định hướng chủ thể (subject-oriented programming)
  • Lập trình phản xạ (reflective programming)
  • Lập trình dòng dữ liệu (dataflow programming) (như các Bản chiết tính hay spreadsheet)

 

3.2 Mẫu hình OOP:

OOP vẫn còn là một đề tài của nhiều tranh cãi về định nghĩa chuẩn xác hay về các nguyên lý của nó.

Trong dạng tổng quát nhất, OOP được hiểu theo cách là một loại thực nghiệm viết chương trình văn bản được phân cấp ra thành nhiều mô đun (module), mà mỗi mô đun đóng vai như một lớp vỏ che đại diện cho mỗi kiểu dữ liệu.

Những khái niệm liên hệ đã được góp nhặt lại để tạo thành một khuôn khổ cho việc lập trình. Các triết lý đằng sau việc định hướng đối tượng đã trở nên mạnh mẽ để tạo thành một sự chuyển đổi mẫu hình trong ngành lập trình.

Những mẫu hình khác như lập trình chức năng và lập trình thủ tục tập trung chủ yếu trên các hành động, còn lập trình lôgíc lại tập trung vào những khẳng định hợp lý để kích hoạt sự thực thi của mã chương trình.

OOP đã phát triển một cách độc lập từ việc nghiên cứu về các ngôn ngữ định hướng của hệ thống mô phỏng, đó là SIMULA 67, và từ việc nghiên cứu các kiến trúc của hệ thống có độ tin cậy cao, đó là các kiến trúc CPU và khả năng cơ bản của các hệ điều hành.

Một chức năng đặc sắc của OOP là việc xử lý các kiểu con của các kiểu dữ liệu.

Dữ liệu của các đối tượng, một cách tổng quát, đuợc đòi hỏi trong thiết kế để thỏa mãn các yêu cầu của người lập trình (tức là các lớp).
Các kiểu dữ liệu bị giới hạn thêm các điều kiện mặc dù có cùng kiểu dữ liệu với loại không bị ràng buộc bởi các điều kiện đó, gọi là kiểu dữ liệu con. Cả hai loại kiểu dữ liệu này đều dựa vào và đều được điều tiết bởi các hành xử (tức là các phương pháp) đã được định nghĩa. Các điều kiện hay yêu cầu này có thể được khai báo rõ ràng hay được giả thiết công nhận ngầm bởi người lập trình. Các ngôn ngữ định hướng đối tượng cung cấp nhiều cơ chế cho việc khẳng định rằng các giả thiết đó có tính địa phương cho một phần của chương trình. Các cơ chế này này có thể đọc thấy trong các tài liệu về các chương trình định hướng đối tượng.

4. Các mẫu hình định hướng đối tượng con

Có nhiều phong cách lập trình hướng đối tượng. Sự khác nhau giữa các phong cách này là tùy theo việc các ngôn ngữ lập trình chú trọng vào khía cạnh nào của sự thuận lợi của định hướng đối tượng và vào việc kết hợp các cấu trúc trong các phương cách khác nhau.

4.1. OOP với các ngôn ngữ cấu trúc

Trong các ngôn ngữ cấu trúc, OOP thường xuất hiện như là một dạng mà ở đó các kiểu dữ liệu được mở rộng để hành xử giống như là một kiểu của một đối tượng trong OOP, hoàn toàn tương tự cho một kiểu dữ liệu trừu tượng với sự mở rộng như là sự kế thừa. Mỗi phương pháp thực ra là một chương trình con mà, một cách cú pháp, giới hạn nội trong một lớp.

4.2. Kiểu tĩnh đối với mẫu hình định hướng đối tưọng

Nhiều ngôn ngữ lập trình hướng đối tượng như là C++ và Java có hệ thống kiểu mà có thể được dùng trong một số cấp độ nào đó để dùng cho việc kiểm lỗi và gia cố các điều kiện của thiết kế định hướng đối tượng. Những tiện lợi của định hướng đối tượng có thể kết hợp với kiểu tĩnh theo nhiều cách. Một số ngôn ngữ định hướng đối tượng như là Eiffel, sẽ bắt buộc không cho thay đổi hệ thống kiểu. Nhiều ngôn ngữ định hướng đối tượng khác thì lại cung cấp các cơ chế cho việc kiểm soát kiểu của các tham số của phương pháp, kiểm soát kiểu dữ liệu của các thành viên công cộng và thành viên cá nhân, kiểm soát kiểu của các các tham chiếu, và kiểm soát sự đúng đắn của tính thừa kế và các quan hệ kiểu con một cách thụ động. Kiểm soát kiểu tĩnh còn có nghĩa là kiểm soát khả năng API, tăng cường các điều kiện của dữ liệu tạo nên trong các thư viện bằng phương pháp định hướng đối tượng và giảm nhẹ số lần kiểm tra kiểu lúc thi hành.

4.3. Các mô hình nguyên mẫu cơ bản

Khác với cách sử dụng lớp, nguyên mẫu là một mô hình khác ít được biết đến hơn, nó có ý nghĩa đạt tới việc chia sẻ ứng xử theo định hướng đối tượng. Sau khi đối tượng được định nghĩa, một đối tuợng khác tương tự sẽ được định nghĩa từ đối tượng ban đầu. Ngôn ngữ nguyên mẫu cơ bản được biết đến nhiều nhất là JavaScript mà đây là một sự thiết lập của ECMAScript. Self, một ngôn ngữ lập trình được phát triển bởi Sun Microsystems cũng là một thí dụ của ngôn ngữ dùng nguyên mẫu cho việc chia sẻ ứng xử chứ không dùng sự phân lớp. NewtonScript, Act1, và Delegation là các thí dụ khác. Đặc biệt, Hybrid và Exemplars sử dụng cả hai mô hình nguyên mẫu và phân lớp. Trong các hệ thống nguyên mẫu, các đối tượng tự chúng là các khuôn thức (template), trong khi các hệ thống phân lớp dùng các lớp như là các khuôn thức cho các đối tượng.

Các tiếp cận kiểu phân lớp thì chiếm đa số trong OOP mà nhiều người sẽ định nghĩa các đối tượng như là có tính chất đóng mà việc chia sẻ dữ liệu xảy ra bởi sự phân lớp và bởi tính kế thừa. Mặc dù vậy, khái niệm tổng quát hơn "chia sẻ ứng xử" được công nhận như là các kỹ thuật thay thế (như trường hợp nguyên mẫu).

4.4. Mô hình đối tượng cơ bản

Lập trình hướng đối tượng cơ bản là trung tâm về việc tạo thành của các đối tượng và các tương tác của chúng, nhưng có thể sẽ thiếu đi một số chức năng quan trọng của mẫu hình định hướng đối tượng lớp cơ bản như là tính kế thừa. Những hệ thống đối tượng cơ bản như vậy thường không được xem như là định hướng đối tượng vì tính kế thừa một cách điển hình là một yếu tố cốt lõi của OOP.

Thí dụ của trường hợp này là ngôn ngữ Visual Basic với các phiên bản 6.0 hay nhỏ hơn.

5. OOP trong văn lệnh

5.1. Văn Lệnh là gì:


Ngôn ngữ văn lệnh gọi tắt là văn lệnh hay còn gọi là ngôn ngữ kịch bản là một ngôn ngữ lập trình ban đầu được thiết kế để dùng trong các máy có khả năng đọc một tập tin văn bản có chứa các câu lện hệ thống và thi hành các câu lệnh trên theo thứ tự từng dòng một. Các Ngôn ngữ văn lệnh thời sơ khai thường được gọi là ngôn ngữ "batch" hay ngôn ngữ điều khiển, trong đó, một  điển hình là MS-DOS batch. Thông thường một vanălệnh được thông dịch trực tiếp bởi hệ điều hành hơn là được biên dịch.

Ngày nay, văn lệnh được xem là mạnh nhất thuộc về các thế hệ văn lệnh Shell tìm thấy trong các hệ điều hành Linux, Unix và tương đương.  Các văn lệnh Shell này không nhừng có khả năng thi hành các câu lệnh thông thường, vòng lặp các hàm,   mà còn có khả năng giới hạn trong việc xử lí các thông tin cấp thấp (như là việc đọc các PCI-ID của các thiết bị phần cứng, tải (load) và giải phóng các bộ điều vận), thay đổi dữ liệu và các biến môi trường (environment variable) cho đến việc xử lí các điều chỉnh các dãy kí tự trong các biến.

Các văn lệnh đã đưọc phát triển ở mức cao được ứng dụng đặc biệt trong Internet đó là các ngôn ngữ như là: HTML (và các thế hệ mới), JavaScript, PHP, Perl, ...

Một ứng dụng đặc biệt của các loại văn lệnh là dùng trong để cho máy tính tiến hành các thao tác hoàn toàn tự động. Các văn lệnh ngày nay có mặt hầu hết trong các hệ điều hành khác nhau trong mọi cấp từ các thao tác nối mạng cho đến thi hành các câu lệnh của hệ điều hành; chúng còn có mặt ngay cả trong các trò chơi, trong các chương trình xử lý văn bản ...

5.2. Các văn lệnh h trợ lập trình hướng đối tượng

Trong những năm gần đây, lập trình đối tượng cơ bản đã đặc biệt trở nên phổ biến trong các ngôn ngữ lập trình văn lệnh vì chúng có tính trừu tượng, tính đóng, khả năng tái sử dụng, và dễ sử dụng (trong khi khả năng kế thừa trong các ngôn ngữ này vẫn còn là các câu hỏi chưa có câu trả lời). Smalltalk có thể là ngôn ngữ đầu tiên có kiểu như trên, PythonRuby là các ngôn ngữ tương đối mới và được xây dựng từ đầu với ý tưởng OOP, trong khi đó ngôn ngữ văn lệnh Perl đã đang được từ từ thêm vào các chức năng mới về định hướng đối tượng kể từ phiên bản 5. Khả năng của các đối tượng để thể hiện "thế giới thực" là một lý do cho sự phổ biến của JavaScript và ECMAScript, mà được bàn cãi là thích hợp để đại diện cho DOM của các hồ sơ HTML và XML trên Internet.

 

6. Thí dụ mã nguồn trong C++


Lưu ý:

  • Thí dụ trên được viết trong C++ có thể dùng bất kì trình dịch nào để dịch thẳng ra tập tin khả thi. Cụ thể là dùng Borland C++ cho Windows hay dùng g++ cho Linux.
  • Các dòng màu đen là mã nguồn, các dòng màu khác là các dòng giải thích ý nghĩa sử dụng của OOP.
  • Đòi hỏi nguời đọc biết ít nhiều cách dùng về ngôn ngữ lập trình và trình dịch.
  • Bản thân các lớp khi khai báo vẫn có tính trừu tượng. Nghĩa là, nó không sử dụng trực tiếp được (mà chỉ có thể xem là các kiểu dữ liệu). Chỉ khi nào người dùng thực hiện động tác thực thể hóa (instantiate) thì lớp này mới khởi động và tạo thành một đối tượng thực. Trong thí dụ này thì câu lệnh Inherit1 boy; và câu lệnh Inherit2 girl; là hai câu lệnh để thực thể hóa thành hai đối tượng boy girl.
  • Sự hỗ trợ các loại đặc tính cho OOP trong C++ rất phong phú. Thí dụ chỉ nhằm minh họa các tính chất cơ bản của OOP.

 

7. Một số khái niệm cần biết trong ngôn ngữ OOP hiện đại

Hiện nay các ngôn ngữ OOP phổ biến nhất đều tập trung theo phương pháp phân lớp trong đó có C++, Java, C# và Visual Basic.NET. Sau đây là một số khái niệm mà các ngôn ngữ này thường dùng tới

7.1. Lớp (class)

Một lớp được hiểu là một kiểu dữ liệu bao gồm các thuộc tính và các phương pháp được định nghĩa từ trước. Đây là sự trừu tượng hóa của đối tượng. Một đối tượng sẽ được xác lập khi nó được thực thể hóa từ một một lớp. Khác với kiểu dữ liệu thông thường, một lớp là một đơn vị (trừu tượng) bao gồm sự kết hợp giữa các phương pháp và các thuộc tính. Để có một đối tượng (mà có thể được xem như là một biến) hoạt động được thì việc thực thể hóa sẽ có thể bao gồm việc cài đặt các giá trị ban đầu của các thuộc tính cũng như việc đăng kí bộ nhớ, mà công việc này thường được giao cho các phương pháp gọi là "máy kết cấu" (constructor) hay hàm dựng. Ngược lại khi một đối tượng thuộc về một lớp không còn sử dụng nữa thì cũng có thể có một phương pháp để xử lý gọi là "máy hủy diệt" (destructor) hay hàm hủy.
Như vậy, để có được các đối tượng thì người lập trình OOP cần phải thiết kế lớp của các đối tượng đó bằng cách xây dựng các thuộc tính và các phương pháp có các đặc tính riêng (xem thí dụ).

Mỗi một phương pháp hay một thuộc tính đầy đủ của một lớp còn được gọi tên là một thành viên (member) của lớp đó.

7.2. Lớp con (subclass)

Lớp con là một lớp thông thường nhưng có thêm tính chất kế thừa một phần hay toàn bộ các đặc tính của một lớp khác. Lớp mà chia sẽ sự kế thừa gọi là lớp phụ mẫu hay lớp cha mẹ (parent class).

7.3. Lớp trừu tượng hay lớp cơ sở trừu tượng (abstract class)

Lớp trừu tượng là một lớp mà nó không thể thực thể hóa thành một đối tượng thực dụng được. Lớp này được thiết kế nhằm tạo ra một lớp có các đặc tính tổng quát nhưng bản thân lớp đó chưa có ý nghĩa (hay không đủ ý nghĩa) để có thể tiến hành viết mã cho việc thực thể hóa. (xem thí dụ)

Thí dụ: Lớp "hinh_phang" được định nghĩa không có dữ liệu nội tại và chỉ có các phương pháp (hàm nội tại) "tinh_chu_vi", "tinh_dien_tich". Nhưng vì lớp hình_phẳng này chưa xác định được đầy đủ các đặc tính của nó (cụ thể các biến nội tại là tọa độ các đỉnh nếu là đa giác, là đường bán kính và toạ độ tâm nếu là hình tròn, ...) nên nó chỉ có thể được viết thành một lớp trừu tượng. Sau đó, người lập trình có thể tạo ra các lớp con chẳng hạn như là lớp "tam_giac", lớp "hinh_tron", lớp "tu_giac",.... Và trong các lớp con này người viết mã sẽ cung cấp các dữ liệu nội tại (như là biến nội tại r làm bán kính và hằng số nội tại Pi cho lớp "hinh_tron" và sau đó viết mã cụ thể cho các phương pháp "tinh_chu_vi" và "tinh_dien_tich").

7.4. Phương pháp (method)

Là hàm nội tại của một lớp (hay một đối tượng). Tùy theo đặc tính mà người lập trình gán cho, một phương pháp có thể chỉ được gọi bên trong các hàm khác của lớp đó, có thể cho phép các câu lệnh bên ngoài lớp gọi tới nó, hay chỉ cho phép các lớp có quan hệ đặc biệt như là quan hệ lớp con, và quan hệ bạn bè (friend) được phép gọi tới nó. Mỗi phương pháp đều có thể có kiểu trả về, chúng có thể trả các kiểu dữ liệu cổ điển hay trả về một kiểu là một lớp đã được định nghĩa từ trước. Một tên gọi khác của phương pháp của một lớp là hàm thành viên

Người ta còn định nghĩa thêm vài loại phương pháp đặc biệt:

  • Hàm dựng (constructor) là hàm được dùng để cài đặt các giá tri ban đầu cho các biến nội tại và đôi khi còn dùng để khai báo về việc sử dụng bộ nhớ.
  • Hàm hủy (destructor) là hàm dùng vào việc làm sạch bộ nhớ và hủy bỏ tên của một đối tượng sau khi đã dùng xong, trong đó có thể bao gồm cả việc xóa các con trỏ nội tại và trả về các phần bộ nhớ mà đối tượng đã dùng.

Trong một số trường hợp thì hàm hủy hay hàm dựng có thể được tự động hóa bởi ngôn ngữ OOP như là trường hợp của Visual C++, C#.

  • Tiện ích (utility) là các hàm chỉ họat động bên trong của một lớp mà không cho phép môi trường bên ngoài gọi tới. Các hàm này có thể là những tính toán trung gian nội bộ của một đối tượng mà xét thấy không cần thiết phải cho thế giới bên ngoài của đối tượng biết là gì.

7.4. Thuộc tính (attribute)

Thuộc tính của một lớp bao gồm các biến, các hằng, hay tham số nội tại của lớp đó. Ở đây, vai trò quan trọng nhất của các thuộc tính là các biến vì chúng sẽ có thể bị thay đổi trong suốt quá trình hoạt động của một đối tượng. Các thuộc tính có thể được xác định kiểu và kiểu của chúng có thể là các kiểu dữ liệu cổ điển hay đó là một lớp đã định nghĩa từ trước. Như đã ghi, khi một lớp đã được thực thể hoá thành đối tượng cụ thể thì tập họp các giá trị của các biến nội tại làm thành trạng thái của đối tượng. Giống như trường hợp của phương pháp, tùy theo người viết mã, biến nội tại có thể chỉ được dùng bên trong các phương pháp của chính lớp đó, có thể cho phép các câu lệnh bên ngoài lớp, hay chỉ cho phép các lớp có quan hệ đặc biệt như là quan hệ lớp con, (và quan hệ bạn bè (friend) trong C++) được phép dùng tới nó (hay thay đổi giá trị của nó). Mỗi thuộc tính của một lớp còn được gọi là thành viên dữ liệu của lớp đó.

7.6. Thực thể (instance)

7.6.1 Thực thể hóa (instantiate) là quá trình khai báo để có một tên (có thể được xem như là một biến) trở thành một đối tượng từ một lớp nào đó.

7.6.2. Thực thể:  Một lớp sau khi được tiến hành thực thể hóa để có một đối tượng cụ thể gọi là một thực thể. Hay nói ngược lại một thực thể là một đối tượng riêng lẽ của một lớp đã định trước. Như các biến thông thường, hai thực thể của cùng một lớp có thể có trạng thái nội tại khác nhau (xác định bởi các giá trị hiện có của các biến nội tại) và do đó hoàn toàn độc lập nhau nếu không có yêu cầu gì đặc biệt từ người lập trình.

7.7. Công cộng (public )

Công cộng là một tính chất được dùng để gán cho các phương pháp, các biến nội tại, hay các lớp mà khi khai báo thì người lập trình đã cho phép các câu lệnh bên ngoài cũng như các đối tượng khác được phép dùng đến nó.

Thí dụ: Trong C++ khai báo public: int my_var; thì biến my_var có hai tính chất là tính công cộng và là một integer cả hai tính chất này hợp thành đặc tính của biến my_var khiến nó có thể được sử dụng hay thay đổi giá trị của nó (bởi các câu lệnh) ở mọi nơi bên ngoài lẫn bên trong của lớp.

7.8. Riêng tư (private )

Riêng tư là sự thể hiện tính chất đóng mạnh nhất (của một đặc tính hay một lớp). Khi dùng tính chất này gán cho một biến, một phương pháp thì biến hay phương pháp đó chỉ có thể được sử dụng bên trong của lớp mà chúng được định nghĩa. Mọi nỗ lực dùng đến chúng từ bên ngoài qua các câu lệnh hay từ các lớp con sẽ bị phủ nhận hay bị lỗi.

7.9. Bảo tồn (protected)

Tùy theo ngôn ngữ, sẽ có vài điểm nhỏ khác nhau về cách hiểu tính chất này. Nhìn chung đây là tính chất mà mà khi dùng để áp dụng cho các phương pháp, các biến nội tại, hay các lớp thì chỉ có trong nội bộ của lớp đó hay các lớp con của nó (hay trong nội bộ một gói như trong Java) được phép gọi đến hay dùng đến các phương pháp, biến hay lớp đó.

So với tính chất riêng tư thì tính bảo tồn rộng rãi hơn về nghĩa chia sẻ dữ liệu hay chức năng. Nó cho phép một số trường hợp được dùng tới các đặc tính của một lớp (từ một lớp con chẳng hạn).

Lưu ý: Các tính chất cộng cộng, riêng tư và bảo tồn đôi khi còn được dùng để chỉ thị cho một lớp con cách thức kế thừa một lớp cha mẹ như trong C++.

7.10. Đa kế thừa (muliple inheritance)

Đây là một tính chất cho phép một lớp con có khả năng kế thừa trực tiếp cùng lúc nhiều lớp khác.

Vài điểm cần lưu ý khi viết mã dùng tính chất đa kế thừa:

  • Khi muốn có một sự kế thừa từ nhiều lớp phụ mẫu thì các lớp này cần phải độc lập và đặc biệt tên của các dữ liệu hay hàm cho phép kế thừa phải có tên khác nhau để tránh lỗi "ambiguilty". Bởi vì lúc đó phần mềm chuyển dịch sẽ không thể xác định được là lớp con sẽ thừa kế tên nào của các lớp phụ mẫu.
  • Không phải ngôn ngữ OOP loại phân lớp nào cũng hỗ trợ cho tính chất này.

Ngoài các khái niệm trên, tùy theo ngôn ngữ, có thể sẽ có các chức năng OOP riêng biệt được cấp thêm vào.

8. Lịch sử Lập trình hướng đối tượng:

Khái niệm về các đối tượng và thực thể trong khoa học máy tính được nhiều người biết đến từ hệ thống PDP-1 của đại học MIT. Đây có lẽ là thí dụ sớm nhất của kiến trúc cơ sở có khả năng thực. Một bằng chứng sớm sủa khác của OOP được tìm thấy qua Sketchpad viết bởi Ivan Sutherland trong năm 1963, tuy nhiên, đây chỉ là một ứng dụng chứ không là một mẫu hình lập trình.

Ngôn ngữ lập trình định hướng đối tượng đầu tiên đã là Simula, ngôn ngữ này được thiết kế để dùng trong các việc mô phỏng, được sáng tạo bởi Ole-Johan Dahl và Kristen Nygaard thuộc Trung Tâm Máy Tính Na Uy ở Oslo. Các kiến thức trong ngôn ngữ này sau đó đã được dùng trong nhiều ngôn ngữ khác, bắt đầu từ Lisp và Pascal cho đến họ ngôn ngữ Smalltalk.

Lập trình hướng đối tượng đã được phát triển như là phương pháp lập trình chủ đạo từ giữa thập niên 1980 nguyên do đáng kể là việc ảnh hưởng của C++, một ngôn ngữ mở rộng của C. Địa vị thống trị của OOP đã được củng cố vững chắc bởi sự phổ biến của các GUI dành cho ngôn ngữ lập trình hướng đối tượng ngày càng tiện lợi. Một thí dụ về quan hệ gần gũi của thư viện GUI động và ngôn ngữ OOP là phần mềm Cocoa, nó là khung cơ sở của Mac OS X dược viết bằng Objective C (Objective C là một loại ngôn ngữ định hướng đối tượng mở rộng của C với việc thông báo động). Công cụ cho OOP cũng được nâng cao phần "lập trình điều khiển theo sự kiện" (mặc dù khái niệm này không chỉ dành cho OOP).

Tại Zürich, Niklaus Wirth và những cộng sự đã theo dõi các đề tài như là dữ liệu trừu tượng và lập trình mô đun. Modula-2 bao gồm cả hai đặc tính đó. Thiết kế liền tiếp theo là Oberon bao gồm sự tiếp cận riêng biệt với việc định hướng đối tượng, các lớp, ... Sự tiếp cận này không như Smalltalk, và cũng khác hẳn C++.

Các chức năng của định hướng đối tượng cũng đã đang được thêm vào nhiều ngôn ngữ trong suốt thời gian đó kể cả ADA, BASIC, Lisp, Fortran, Pascal và nhiều nữa. Việc cộng thêm các chức năng đó cho các ngôn ngữ mà được trước đó không chủ định thiết kế cho chúng ngay từ đầu cũng thường dẫn tới nhiều khó khăn trong khả năng tương thích (với mã nguồn viết cho các phiên bản cũ) và khả năng bảo trì mã. Điển hình của trường hợp này là Pascal và Visual Basic. Các ngôn ngữ thuần túy định hướng đối tượng, ở phía khác, lại thiếu các đặc tính mà nhiều người lập trình phụ thuộc vào. Để bắc cầu cho khoảng trống này, nhiều nỗ lực đã được xúc tiến dể tạo ra các ngôn ngữ đặt cơ sở trên các phương pháp định hướng đối tượng nhưng lại cho phép dùng nhiều đặc tính lập trình cấu trúc theo những phương cách "an toàn". Ngôn ngữ Eiffel của Bertrand Meyer đã sớm thành công với các mục tiêu này.

Trong thập niên qua, Java được dùng rộng rãi một phần là do sự tương tự với C và C++, nhưng có lẽ do phần khác quan trọng hơn là việc lắp đặt sử dụng máy ảo mà chủ ý là thực thi cùng một mã nguồn cho nhiều nền tảng khác nhau. Microsoft.NET cũng mở đầu với các chủ ý tương tự và cộng thêm việc hỗ trợ nhiều ngôn ngữ hay các sự biến thể của các ngôn ngữ cũ (như trưòng hợp C# và Visual Basic).

Gần đây, một số ngôn ngữ xuất hiện với chức năng chính là định hướng đối tượng nhưng lại tương thích được với phương pháp thủ tục như là Python và Ruby. Bên cạnh Java, C# và Visual Basic.NET là hai ngôn ngữ OOP quan trọng hiện tại thiết kế bởi Microsoft.

Giống như lập trình thủ tục đã dẫn tới việc tinh lọc các kỹ thuật như là lập trình cấu trúc, phần mềm định hướng đối tượng hiện đại thiết kế các phương pháp bao gồm các sự tinh lọc. Chẳng hạn như là việc ứng dụng các dạng thức thiết kế, thiết kế bởi hợp đồng và các ngôn ngữ mô hình trong đó có UML.

 

9. Các ngôn ngữ lập trình hỗ trợ hướng đối tượng:

  • C#
  • C++
  • Common Lisp Object System
  • Eiffel
  • Fortran 2003
  • Java
  • Objective-C
  • OCaml
  • Object Pascal
  • Perl
  • PHP

  • Python
  • Ruby
  • Simula
  • Sleep
  • Smalltalk
  • ADA

Tài liệu tham khảo

  • http://wikipediw.org  Anh ngữ và Việt ngữ
  • H.M. Deitel/P.J.Deitel : C++ How to Program,  Prentice hall, ISBN 0131173340
  • Tom Swan: Mastering Borland C++, SAMS, ISBN 0672302748
  • Grady Booch: Object-Oriented Analysis and Design with Applications, Addison-Wesley, ISBN 0805353402
  • Alan Kay: The Early History of Smalltalk
  • Erich Gamma, Richard Helm, Ralph Johnson, John Vlissides: Design Patterns: Elements of Reusable Object Oriented Software, Addison-Wesley, ISBN 0201633612
  • Bertrand Meyer: Object-Oriented Software Construction, Prentice Hall, ISBN 0136291554
  • James Rumbaugh, Michael Blaha, William Premerlani, Frederick Eddy, William Lorensen: Object-Oriented Modeling and Design, Prentice Hall, ISBN 0136298419
  • Ivar Jacobson: Object-Oriented Software Engineering: A Use Case-Driven Approach, Addison-Wesley, ISBN 0201544350
  • Harold Abelson, Gerald Jay Sussman, Julie Sussman: Structure and Interpretation of Computer Programs, The MIT Press, ISBN 0262011530
  • Martin Abadi, Luca Cardelli: A Theory of Objects, Springer-Verlag, ISBN 0-387-94775-2
  • Paul Harmon, William Morrissey: The Object Technology Casebook - Lessons from Award-Winning Business Applications, John Wiley & Sons, ISBN 0-471-14717-6
  • David A. Taylor: Object-Oriented Information Systems - Planning and Implementation, John Wiley & Sons, ISBN 0-471-54364-0
  • Peter Eeles, Oliver Sims: Building Business Objects, John Wiley & Sons, ISBN 0-471-19176-0

 

           © http://vivàsciences.free.fr  http://vivàsciences.nvà  Võ Quang Nhân