Giới thiệu
Lập trình hướng đối tượng (tiếng Anh: Object-oriented programming, viết tắt: OOP) là một mô hình kiến trúc lập trình dựa trên khái niệm “công nghệ đối tượng”, mà trong đó, đối tượng chứa đựng các dữ liệu: (i) thuộc tính của đối tượng; (ii) phương thức để thực thi các hành động của đố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.
Một số khái niệm cơ bản
Khái niệm đầu tiên là “đối tượng”, được hiểu như là 1 thực thể: người, vật hoặc 1 bảng dữ liệu, . . .
Một đối tượng bao gồm 2 thông tin chính:
Thuộc tính. Là những thông tin, đặc điểm của đối tượng. Ví dụ: một hình chữ nhật sẽ có chiều dài, chiều rộng, . . .
Phương thức. Là những thao tác, hành động mà đối tượng đó có thể thực hiện. Ví dụ: một hình chữ nhật sẽ có thao tác tính chu vi, diện tích, . . .
Khái niệm thứ hai là “lớp”, được hiểu như là một khuôn mẫu mà từng đối tượng là một thể hiện cụ thể dựa trên khuôn mẫu đó.
Ví dụ một lớp hình chữ nhật sẽ định nghĩa: (i) các thuộc tính chiều dài / chiều rộng; (ii) các phương thức tính chu vi, tính diện tích. Còn từng đối tượng hình chữ nhật sẽ có số đo cụ thể cho từng thuộc tính cũng như chu vi và diện tích riêng.
Các tính chất của lập trình hướng đối tượng
Tính đóng gói (encapsulation) và che giấu thông tin (information hiding):
- Tính chất này không cho phép tác nhân bên ngoài thay đổi trạng thái nội tại của một đối tượng.
- Chỉ có các phương thức nội tại của đối tượng cho phép thay đổi trạng thái của nó.
- Đây là tính chất đảm bảo sự toàn vẹn của đối tượng.
Tính trừu tượng (abstraction):
- Là phương pháp trừu tượng hóa định nghĩa lên những hành động, tính chất của loại đối tượng nào đó cần phải có.
- Mỗi đối tượng 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 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ó thông qua kế thừa.
- Đ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ó mà không phải tiến hành định nghĩa lại.
Tính đa hình (polymorphism):
- Thể hiện thông qua việc gửi các thông điệp (message).
- Việc gửi các thông điệp này có thể so sánh như việc gọi các phương thức bên trong của một đối tượng.
- Các phương thức dùng trả lời cho một thông điệp sẽ tùy theo đối tượng mà thông điệp đó được gửi tới sẽ có phản ứng khác nhau.
Xây dựng lớp đối tượng độc lập
Trong nội dung bài này, chúng ta cùng tìm hiểu cách xây dựng một lớp đối tượng độc lập cùng với tính chất đóng gói (encapsulation) bằng ngôn ngữ Python.
Bước 1.
Chúng ta tạo một PyDev Project trong Eclipse IDE và đặt tên là PythonOOPFirstProject.
Chúng ta tiếp tục tạo package main và module Main.py cùng phương thức main() mặc định.

Bước 2.
Chúng ta tạo package object và module HinhChuNhat.py.

Những kỹ thuật lập trình cần chú ý:
- Như đã trình bày ở phần Giới thiệu về Tính đóng gói (encapsulation) và che giấu thông tin (information hiding). Mỗi
packagecó thể được xem như là một hình thức để gom nhóm các lớp đối tượng có cùng chung những đặc điểm nào đó.
- Python là một ngôn ngữ lập trình rất linh động và hỗ trợ nhiều phong cách lập trình khác nhau. Chúng ta có thể tự do lựa chọn việc có đặt một
modulevào bên trong mộtpackagehay không. Tuy nhiên, để dễ quản lý một chương trình phần mềm lớn, chúng ta nên phân hoạch cácmodulevào trong nhữngpackagetheo tư duy hướng đối tượng.
- Trong ví dụ hiện tại, chúng ta có thể đặt tên
packagelàobject(nghĩa là đối tượng nói chung) hoặcshape(nghĩa là hình vẽ nói chung).
Bước 3.
Khác với nhóm ngôn ngữ Java / Csharp, Python không cung cấp một cách tường minh để định nghĩa các thuộc tính của một lớp đối tượng. Về cơ bản, mọi thuộc tính hay phương thức trong một module của Python đều là public và được truy xuất tự do từ các module khác. Điều này có vẻ không thực sự phù hợp theo tư duy lập trình hướng đối tượng.
Để phù hợp Tính đóng gói (encapsulation) và che giấu thông tin (information hiding) trong Lập trình hướng đối tượng, Python cung cấp 02 cách tiếp cận để định nghĩa các phương thức đặc biệt truy xuất và điều chỉnh dữ liệu, hay còn được gọi là các getter và setter.
Cách tiếp cận thứ nhất:
- Định nghĩa cặp phương thức
get/setđể truy xuất và điều chỉnh thông tin cho thuộc tính tương ứng.
- Xác lập tính chất ẩn của cặp phương thức này bằng cách thêm “
__” vào phía trước tên phương thức. Thực ra chúng ta không bắt buộc phải thực hiện bước này. Chúng ta có thể sử dụng hai phương thức này ở cácmodulekhác. Nhưng chúng ta sẽ thấy rằng có đến 02 cách truy xuất và điều chỉnh dữ liệu: (i) thông qua một hình thức được gọi làproperties; (ii) thông qua hai phương thức này. Và như vậy sẽ không phù hợp với triết lý của Python là chỉ nên có một cách thực hiện một tác vụ.
- Định nghĩa hình thức
propertiesbằng cách sử dụng phương thức đặc biệt làproperty(). Phương thức này có 04 tham số lần lượt là các phương thức được định nghĩa với ý nghĩa: (i)get()để truy xuất thuộc tính; (ii)set()để điều chỉnh thông tin thuộc tính; (iii)del()để xóa thông tin thuộc tính; (iv)doc()để tạo một mô tả cho thuộc tính. Ở đây chúng ta chỉ cần đến 02 tham số đầu tiên làget/set.
- Chúng ta có thể sử dụng các
propertiesnày như là một thuộc tính của đối tượng. Theo quy tắc chung, tên của từngpropertiesnên được đặt trùng với tên của thuộc tính, chỉ có một điểm khác là chữ cái đầu viết hoa.

Cách tiếp cận thứ hai:
- Định nghĩa hình thức
propertiesbằng cách sử dụngdecorator @property.
Decoratorslà công cụ rất mạnh mẽ và hữu ích trong Python vì nó cho phép các lập trình viên sửa đổi hành vi của phương thức hoặc thuộc tính.Decoratorscho phép chúng ta bọc một phương thức khác để mở rộng hành vi của phương thức được bọc, mà không sửa đổi vĩnh viễn. Chúng ta sẽ dần dần tìm hiểu kỹ thuật lập trình này trong những bài tiếp theo.

Bước 4.
Chúng ta định nghĩa constructor cho lớp đối tượng.

Những kỹ thuật lập trình cần chú ý:
Constructorlà một dạng đặc biệt của phương thức, được sử dụng để khởi tạo các đối tượng.
Constructorđược gọi tại thời điểm tạo đối tượng. Nó khởi tạo các giá trị để cung cấp dữ liệu cho các đối tượng, đó là lý do tại sao nó được gọi làconstructor.
- Khác với nhóm ngôn ngữ Java / C#, Python chỉ cung cấp một phương thức
constructorduy nhất là__init__(). Chúng ta sẽ chủ động quyết định xem có để tham số choconstructorhay không. Cách thức được sử dụng ở đây là gán sẵn giá trịtên_tham_số = Nonevà kiểm tra.
- Từ khóa
selfgiúp chúng ta liên hệ đến thuộc tính hoặc phương thức nội tại của lớp đối tượng. Chúng ta sử dụng từ khóa này để phân biệt khi muốn định nghĩa các biến có cùng tên với các thuộc tính hoặc phương thức nội tại của lớp.
- Đối với thuộc tính
chieuDai, chúng ta đã sử dụng cách tiếp cận thứ nhất bên trên để định nghĩaproperties chieuDai. Do vậy chúng ta không cần định nghĩa tường minh thuộc tính này mà chỉ cần gọi phương thức ẩn__setChieuDai().
- Đối với thuộc tính
chieuRong, chúng ta đã sử dụng cách tiếp cận thứ hai bên trên để định nghĩaproperties ChieuRong. Do vậy chúng ta định nghĩa tường minh thuộc tính ẩn__chieuRong.
Bước 5.
Chúng ta định nghĩa các phương thức tính chu vi và diện tích hình chữ nhật:

Bước 6.
Chúng ta thực hiện thử nghiệm tạo mới 02 hình chữ nhật và tính chu vi, diện tích:

Những kỹ thuật lập trình cần chú ý:
- Để truy xuất đến những lớp đối tượng ở một
packagekhác, chúng ta sử dụng từ khóafromvàimport. Ví dụ ở đây làfrom object import HinhChuNhat.
- Chúng ta khởi tạo một đối tượng thực bằng cách gọi tên của
modulevà tên của lớp bên trong, ví dụ ở đây làMyClass(). Tùy thuộc vào tham số được truyền thì constructor__init__()sẽ thực thi việc khởi tạo giá trị tương ứng cho các thuộc tính.
- Ví dụ ở đây. Đối tượng
hinhChuNhatAđược khởi tạo vớiconstructormặc định không có tham số. Như vậy sẽ sử dụngpropertiesđể điều chỉnh thông tin cho thuộc tính của đối tượng. Đối tượnghinhChuNhatBđược khởi tạo vớiconstructorcó tham số.
Bước 7.
Chúng ta thực thi toàn bộ project để kiểm tra kết quả thử nghiệm:

Tổng kết
Trong bài này, chúng ta đã cùng nhau tìm hiểu những kiến thức cơ bản về lớp đối tượng cũng như những tính chất về lập trình hướng đối tượng.
Chúng ta đã cùng nhau thực hiện một ví dụ nhỏ về lớp đối tượng với ngôn ngữ Python.
Trong các bài tiếp theo, chúng ta sẽ tiếp tục tìm hiểu những kiến thức khác xung quanh lập trình hướng đối tượng.















