Lập trình hướng đối tượng – Phần 3 – Tính chất đa hình (polymorphism), lớp trừu tượng (abstract class) và giao diện (interface) – Python

Giới thiệu

Trong nội dung bài viết này, chúng ta cùng nhau tìm hiểu cách thức mà Java hỗ trợ việc thực hiện những thuật ngữ về Lập trình hướng đối tượng: (i) tính chất trừu tượng – abstraction; (ii) tính chất đa hình – polymorphism; (iii) lớp trừu tượng – abstract class; (iv) giao diện – interface.

Không giống như những ngôn ngữ lập trình khác như Java / C# / PHP, quan điểm của Python là một sự linh động hết sức có thể. Chúng ta có thể tham khảo những đặc trưng của quan điểm Python như sau (https://www.python.org/dev/peps/pep-0020/):

  • Đẹp thì tốt hơn xấu.
  • Rõ ràng là tốt hơn so với ngầm.
  • Đơn giản là tốt hơn phức hợp.
  • Phức hợp tốt hơn phức tạp.
  • Bằng phẳng là tốt hơn so với lồng nhau.
  • Thưa thì tốt hơn dày đặc.
  • Tính dễ đọc.
  • Trường hợp đặc biệt không đủ đặc biệt để phá vỡ các quy tắc.
  • Mặc dù thực tế đánh bại sự tinh khiết.
  • Lỗi không bao giờ nên âm thầm vượt qua.
  • Trừ khi im lặng rõ ràng.
  • Trước sự mơ hồ, hãy từ chối sự cám dỗ để đoán.
  • Nên có một – và tốt nhất là chỉ có một cách rõ ràng để làm điều đó.
  • Mặc dù cách đó ban đầu có thể không rõ ràng trừ khi bạn là người Hà Lan.
  • Bây giờ tốt hơn không bao giờ.
  • Mặc dù không bao giờ thường tốt hơn * ngay * bây giờ.
  • Nếu việc thực hiện khó giải thích, đó là một ý tưởng tồi.
  • Nếu việc thực hiện khó giải thích, đó là một ý tưởng tồi.
  • Namespaces là một ý tưởng tuyệt vời – hãy làm nhiều hơn nữa!

Đối với tính chất đa hình cũng vậy, Python xem khái niệm abstract classinterface là như nhau và dưới một sự thể hiện duy nhất là abstract class.

Như vậy chúng ta muốn phân tích và thiết kế một chương trình hướng đối tượng càng thuần túy, thì chúng ta phải phân hoạch các class dựa vào tư duy Lập trình hướng đối tượng.

Chúng ta thiết kế một chương trình nhỏ bao gồm các lớp và giao diện như sau:

  • Lớp trừu tượng: PhuongTienGiaoThong.
  • Các lớp đối tượng ở tầng dưới thứ hai: PhuongTienDuongBo; PhuongTienDuongThuy; PhuongTienDuongKhong.
  • Các lớp đối tượng ở tầng dưới cùng: Oto; XeMay; XeDap; TauThuy; Thuyen; MayBay; KhinhKhiCau; ThuyPhiCo.
  • Giao diện ở cấp cao nhất: HoatDong.
  • Giao diện ở tầng dưới: CoTheChay; CoTheBay; CoTheBoi.

Thiết kế Lớp trừu tượng

Bước 1.

Chúng ta thực hiện tạo PyDev Project trong Eclipse IDE và đặt tên là PythonOOPThirdProject.

Chúng ta thực hiện tạo package mainfile Main.py.

Bước 2.

Chúng ta thực hiện tạo package object.

Chúng ta thực hiện tạo class PhuongTienGiaoThong.

Những điểm cần chú ý:

  • Cách thức để định nghĩa một lớp đối tượng trong Python là kế thừa từ lớp ABC (viết tắt của Abstract Base Class) trong module abc.

Bước 3.

Chúng ta thực hiện tạo class PhuongTienDuongBo là một dẫn xuất của class PhuongTienGiaoThong.

Bước 4.

Chúng ta thực hiện tạo class PhuongTienDuongThuy là một dẫn xuất của class PhuongTienGiaoThong.

Bước 5.

Chúng ta thực hiện tạo class PhuongTienDuongKhong là một dẫn xuất của class PhuongTienGiaoThong.

Thiết kế Lớp đối tượng

Bước 1.

Chúng ta thực hiện tạo class Oto là một dẫn xuất của class PhuongTienDuongBo.

Bước 2.

Chúng ta thực hiện tạo class XeMay là một dẫn xuất của class PhuongTienDuongBo.

Bước 3.

Chúng ta thực hiện tạo class XeDap là một dẫn xuất của class PhuongTienDuongBo.

Bước 4.

Chúng ta thực hiện tạo class Thuyen là một dẫn xuất của class PhuongTienDuongThuy.

Bước 5.

Chúng ta thực hiện tạo class TauThuy là một dẫn xuất của class PhuongTienDuongThuy.

Bước 6.

Chúng ta thực hiện tạo class MayBay là một dẫn xuất của class PhuongTienDuongKhong.

Bước 7.

Chúng ta thực hiện tạo class KhinhKhiCau là một dẫn xuất của class PhuongTienDuongKhong.

Bước 8.

Chúng ta thực hiện tạo class ThuyPhiCo là một dẫn xuất của class PhuongTienGiaoThong.

Thiết kế Giao diện

Bước 1.

Chúng ta thực hiện tạo package action.

Chúng ta thực hiện tạo abstract class CoTheChay đóng vai trò như một interface.

Bước 2.

Chúng ta thực hiện tạo abstract class CoTheBoi đóng vai trò như một interface.

Bước 3.

Chúng ta thực hiện tạo abstract class CoTheBay đóng vai trò như một interface.

Bước 4.

Chúng ta thực hiện tạo abstract class HoatDong đóng vai trò như một interface, là class cơ sở của các class: CoTheChay; CoTheBay; CoTheBoi.

Thiết kế Tính đa hình thứ nhất

Bước 1.

Chúng ta đặc tả những đặc trưng của abstract class PhuongTienGiaoThong:

  • Thuộc tính: soLuongBanhXe; soLuongChoNgoi.
  • Những phương thức get / set.
  • Phương thức trừu tượng: gioiThieu().

Chú ý rằng những đặc trưng này sẽ được kế thừa lại hoàn toàn từ những lớp dẫn xuất của PhuongTienGiaoThong trên cây gia phả.

Những điểm cần chú ý:

  • Chúng ta sử dụng decorator @abstractmethod trong module abc để định nghĩa một phương thức trừu tượng.

Bước 2.

Chúng ta đặc tả những đặc trưng của class PhuongTienDuongBo:

  • Thuộc tính. Đầu tiên là kế thừa những thuộc tính từ lớp cơ sở PhuongTienGiaoThong. Tiếp đến là định nghĩa thêm 01 thuộc tính riêng biệt: loaiDongCo.
  • Phương thức. Đầu tiên là kế thừa trọn vẹn những phương thức get / set đối với những thuộc tính được đặc tả ở lớp cơ sở PhuongTienGiaoThong. Tiếp đến là định nghĩa các phương thức get / set đối với thuộc tính loaiDongCo.
  • Kế thừa và đặc tả lại phương thức gioiThieu(). Đây là một phương thức được sử dụng trong ví dụ về tính chất đa hình.

Chú ý rằng những đặc trưng này sẽ được kế thừa lại hoàn toàn từ những lớp dẫn xuất của PhuongTienDuongBo trên cây gia phả.

Bước 3.

Chúng ta đặc tả những đặc trưng của class PhuongTienDuongKhong:

  • Thuộc tính. Đầu tiên là kế thừa những thuộc tính từ lớp cơ sở PhuongTienGiaoThong. Tiếp đến là định nghĩa thêm 02 thuộc tính riêng biệt: soLuongCanh; soLuongQuat.
  • Phương thức. Đầu tiên là kế thừa trọn vẹn những phương thức get / set đối với những thuộc tính được đặc tả ở lớp cơ sở PhuongTienGiaoThong. Tiếp đến là định nghĩa các phương thức get / set đối với thuộc tính soLuongCanh; soLuongQuat.
  • Kế thừa và đặc tả lại phương thức gioiThieu(). Đây là một phương thức được sử dụng trong ví dụ về tính chất đa hình.

Chú ý rằng những đặc trưng này sẽ được kế thừa lại hoàn toàn từ những lớp dẫn xuất của PhuongTienDuongKhong trên cây gia phả.

Bước 4.

Chúng ta đặc tả những đặc trưng của class PhuongTienDuongThuy:

  • Thuộc tính. Đầu tiên là kế thừa những thuộc tính từ lớp cơ sở PhuongTienGiaoThong. Tiếp đến là định nghĩa thêm 01 thuộc tính riêng biệt: loaiBanhLai.
  • Phương thức. Đầu tiên là kế thừa trọn vẹn những phương thức get / set đối với những thuộc tính được đặc tả ở lớp cơ sở PhuongTienGiaoThong. Tiếp đến là định nghĩa các phương thức get / set đối với thuộc tính loaiBanhLai.
  • Kế thừa và đặc tả lại phương thức gioiThieu(). Đây là một phương thức được sử dụng trong ví dụ về tính chất đa hình.

Chú ý rằng những đặc trưng này sẽ được kế thừa lại hoàn toàn từ những lớp dẫn xuất của PhuongTienDuongThuy trên cây gia phả.

Bước 5.

Chúng ta đặc tả những đặc trưng của class Oto:

  • Thuộc tính. Kế thừa trọn vẹn những thuộc tính từ lớp cơ sở PhuongTienDuongBo.
  • Phương thức. Kế thừa và đặc tả lại phương thức gioiThieu(). Đây là một phương thức được sử dụng trong ví dụ về tính chất đa hình.

Bước 6.

Chúng ta đặc tả những đặc trưng của class XeMay:

  • Thuộc tính. Kế thừa trọn vẹn những thuộc tính từ lớp cơ sở PhuongTienDuongBo.
  • Phương thức. Kế thừa và đặc tả lại phương thức gioiThieu(). Đây là một phương thức được sử dụng trong ví dụ về tính chất đa hình.

Bước 7.

Chúng ta đặc tả những đặc trưng của class XeDap:

  • Thuộc tính. Kế thừa trọn vẹn những thuộc tính từ lớp cơ sở PhuongTienDuongBo.
  • Phương thức. Kế thừa và đặc tả lại phương thức gioiThieu(). Đây là một phương thức được sử dụng trong ví dụ về tính chất đa hình.

Bước 8.

Chúng ta đặc tả những đặc trưng của class MayBay:

  • Thuộc tính. Kế thừa trọn vẹn những thuộc tính từ lớp cơ sở PhuongTienDuongKhong.
  • Phương thức. Kế thừa và đặc tả lại phương thức gioiThieu(). Đây là một phương thức được sử dụng trong ví dụ về tính chất đa hình.

Bước 9.

Chúng ta đặc tả những đặc trưng của class KhinhKhiCau:

  • Thuộc tính. Kế thừa trọn vẹn những thuộc tính từ lớp cơ sở PhuongTienDuongKhong.
  • Phương thức. Kế thừa và đặc tả lại phương thức gioiThieu(). Đây là một phương thức được sử dụng trong ví dụ về tính chất đa hình.

Bước 10.

Chúng ta đặc tả những đặc trưng của class TauThuy:

  • Thuộc tính. Kế thừa trọn vẹn những thuộc tính từ lớp cơ sở PhuongTienDuongThuy.
  • Phương thức. Kế thừa và đặc tả lại phương thức gioiThieu(). Đây là một phương thức được sử dụng trong ví dụ về tính chất đa hình.

Bước 11.

Chúng ta đặc tả những đặc trưng của class Thuyen:

  • Thuộc tính. Kế thừa trọn vẹn những thuộc tính từ lớp cơ sở PhuongTienDuongThuy.
  • Phương thức. Kế thừa và đặc tả lại phương thức gioiThieu(). Đây là một phương thức được sử dụng trong ví dụ về tính chất đa hình.

Bước 12.

Chúng ta đặc tả những đặc trưng của class ThuyPhiCo:

  • Thuộc tính. Đầu tiên là kế thừa những thuộc tính từ lớp cơ sở PhuongTienGiaoThong. Tiếp đến là định nghĩa thêm 02 thuộc tính riêng biệt: loaiBanhLai; soLuongCanh.
  • Phương thức. Đầu tiên là kế thừa trọn vẹn những phương thức get / set đối với những thuộc tính được đặc tả ở lớp cơ sở PhuongTienGiaoThong. Tiếp đến là định nghĩa các phương thức get / set đối với thuộc tính loaiBanhLai; soLuongCanh.
  • Kế thừa và đặc tả lại phương thức gioiThieu(). Đây là một phương thức được sử dụng trong ví dụ về tính chất đa hình.

Bước 13.

Chúng ta thực hiện thử nghiệm tính đa hình như bên dưới.

Chúng ta có thể nhận thấy những điểm rất rõ ở đây là:

  • Thực thể của đối tượng nào thì sẽ tự biết mình là ai.
  • Và như vậy sẽ tự thực hiện một cách chính xác phương thức gioiThieu() cũng như các phương thức get / set của các thuộc tính được đặc tả trong lớp trừu tượng PhuongTienGiaoThong.

Bước 14.

Kết quả thực hiện thử nghiệm đa hình thứ nhất như sau:

Thiết kế Tính đa hình thứ hai

Bước 1.

Chúng ta định nghĩa phương thức trừu tượng thongBao() trong class cơ sở HoatDong.

Bước 2.

Chúng ta định nghĩa class CoTheChay kế thừa từ class HoatDong:

  • Kế thừa việc định nghĩa các phương thức trừu tượng từ class HoatDong.
  • Định nghĩa phương thức trừu tượng riêng biệt: chay().

Bước 3.

Chúng ta định nghĩa class CoTheBoi kế thừa từ class HoatDong:

  • Kế thừa việc định nghĩa các phương thức trừu tượng từ class HoatDong.
  • Định nghĩa phương thức trừu tượng riêng biệt: boi().

Bước 4.

Chúng ta định nghĩa class CoTheBay kế thừa từ class HoatDong:

  • Kế thừa việc định nghĩa các phương thức trừu tượng từ class HoatDong.
  • Định nghĩa phương thức trừu tượng riêng biệt: bay().

Bước 5.

Chúng ta điều chỉnh class PhuongTienDuongBo để thuộc phạm vi ảnh hưởng của class CoTheChay:

Bước 6.

Chúng ta điều chỉnh class PhuongTienDuongThuy để thuộc phạm vi ảnh hưởng của class CoTheBoi:

Bước 7.

Chúng ta điều chỉnh class PhuongTienDuongKhong để thuộc phạm vi ảnh hưởng của class CoTheBay:

Bước 8.

Chúng ta điều chỉnh class ThuyPhiCo để thuộc phạm vi ảnh hưởng của class CoTheChayCoTheBoi.

Bước 9.

Chúng ta điều chỉnh class Oto:

Bước 10.

Chúng ta điều chỉnh class XeMay:

Bước 11.

Chúng ta điều chỉnh class XeDap:

Bước 12.

Chúng ta điều chỉnh class MayBay:

Bước 13.

Chúng ta điều chỉnh class KhinhKhiCau:

Bước 14.

Chúng ta điều chỉnh class TauThuy:

Bước 15.

Chúng ta điều chỉnh class Thuyen:

Bước 16.

Chúng ta điều chỉnh lại ví dụ về tính đa hình như bên dưới.

Chúng ta cần kiểm tra một chút để biết thực thể của đối tượng nào bằng cách sử dụng từ khóa isinstance.

Tổng kết

Trong bài này, chúng ta đã cùng nhau tìm hiểu sự hỗ trợ của Python trong việc thực hiện tính chất đa hình trong Lập trình hướng đối tượng.

Hi vọng với bài này thì chúng ta đã có cái nhìn tổng quát hơn về cả 04 tính chất đặc trưng nhất của Lập trình hướng đối tượng.

Lập trình hướng đối tượng – Phần 3 – Tính chất đa hình (polymorphism), lớp trừu tượng (abstract class) và giao diện (interface) – PHP

Giới thiệu

Trong nội dung bài viết này, chúng ta cùng nhau tìm hiểu cách thức mà Java hỗ trợ việc thực hiện những thuật ngữ về Lập trình hướng đối tượng: (i) tính chất trừu tượng – abstraction; (ii) tính chất đa hình – polymorphism; (iii) lớp trừu tượng – abstract class; (iv) giao diện – interface.

Chúng ta thiết kế một chương trình nhỏ bao gồm các lớp và giao diện như sau:

  • Lớp trừu tượng: PhuongTienGiaoThong.
  • Các lớp đối tượng ở tầng dưới thứ hai: PhuongTienDuongBo; PhuongTienDuongThuy; PhuongTienDuongKhong.
  • Các lớp đối tượng ở tầng dưới cùng: Oto; XeMay; XeDap; TauThuy; Thuyen; MayBay; KhinhKhiCau; ThuyPhiCo.
  • Các lớp đối tượng ở tầng dưới cùng: Oto; XeMay; XeDap; TauThuy; Thuyen; MayBay; KhinhKhiCau; ThuyPhiCo.
  • Giao diện ở cấp cao nhất: HoatDong.
  • Giao diện ở tầng dưới: CoTheChay; CoTheBay; CoTheBoi.

Thiết kế Lớp trừu tượng

Bước 1.

Chúng ta thực hiện tạo PHP Project trong Eclipse IDE và đặt tên là PHPOOPThirdProject.

Chúng ta thực hiện tạo folder mainfile index.php.

Bước 2.

Chúng ta thực hiện tạo folder object.

Chúng ta thực hiện tạo class PhuongTienGiaoThong.

Những điểm cần chú ý:

  • Đây là một lớp trừu tượng, nên chúng ta sử dụng từ khóa abstract phía trước định nghĩa tên của class.

Bước 3.

Chúng ta thực hiện tạo class PhuongTienDuongBo là một dẫn xuất của class PhuongTienGiaoThong.

Bước 4.

Chúng ta thực hiện tạo class PhuongTienDuongThuy là một dẫn xuất của class PhuongTienGiaoThong.

Bước 5.

Chúng ta thực hiện tạo class PhuongTienDuongKhong là một dẫn xuất của class PhuongTienGiaoThong.

Thiết kế Lớp đối tượng

Bước 1.

Chúng ta thực hiện tạo class Oto là một dẫn xuất của class PhuongTienDuongBo.

Bước 2.

Chúng ta thực hiện tạo class XeMay là một dẫn xuất của class PhuongTienDuongBo.

Bước 3.

Chúng ta thực hiện tạo class XeDap là một dẫn xuất của class PhuongTienDuongBo.

Bước 4.

Chúng ta thực hiện tạo class Thuyen là một dẫn xuất của class PhuongTienDuongThuy.

Bước 5.

Chúng ta thực hiện tạo class TauThuy là một dẫn xuất của class PhuongTienDuongThuy.

Bước 6.

Chúng ta thực hiện tạo class MayBay là một dẫn xuất của class PhuongTienDuongKhong.

Bước 7.

Chúng ta thực hiện tạo class KhinhKhiCau là một dẫn xuất của class PhuongTienDuongKhong.

Bước 8.

Chúng ta thực hiện tạo class ThuyPhiCo là một dẫn xuất của class PhuongTienGiaoThong.

Thiết kế Giao diện

Bước 1.

Chúng ta thực hiện tạo folder action.

Chúng ta thực hiện tạo interface CoTheBoi.

Những điểm cần chú ý:

  • Chúng ta sử dụng từ khóa interface đứng trước định nghĩa tên của giao diện.

Bước 2.

Chúng ta thực hiện tạo interface CoTheBay.

Bước 3.

Chúng ta thực hiện tạo interface CoTheChay.

Bước 4.

Chúng ta thực hiện tạo interface HoatDong là giao diện cơ sở của các giao diện: CoTheChay; CoTheBay; CoTheBoi.

Thiết kế Tính đa hình thứ nhất

Bước 1.

Chúng ta đặc tả những đặc trưng của abstract class PhuongTienGiaoThong:

  • Thuộc tính: soLuongBanhXe; soLuongChoNgoi.
  • Những phương thức get / set.
  • Phương thức trừu tượng: gioiThieu().

Chú ý rằng những đặc trưng này sẽ được kế thừa lại hoàn toàn từ những lớp dẫn xuất của PhuongTienGiaoThong trên cây gia phả.

Bước 2.

Chúng ta đặc tả những đặc trưng của class PhuongTienDuongBo:

  • Thuộc tính. Đầu tiên là kế thừa những thuộc tính từ lớp cơ sở PhuongTienGiaoThong. Tiếp đến là định nghĩa thêm 01 thuộc tính riêng biệt: loaiDongCo.
  • Phương thức. Đầu tiên là kế thừa trọn vẹn những phương thức get / set đối với những thuộc tính được đặc tả ở lớp cơ sở PhuongTienGiaoThong. Tiếp đến là định nghĩa các phương thức get / set đối với thuộc tính loaiDongCo.
  • Kế thừa và đặc tả lại phương thức gioiThieu(). Đây là một phương thức được sử dụng trong ví dụ về tính chất đa hình.

Chú ý rằng những đặc trưng này sẽ được kế thừa lại hoàn toàn từ những lớp dẫn xuất của PhuongTienDuongBo trên cây gia phả.

Bước 3.

Chúng ta đặc tả những đặc trưng của class PhuongTienDuongKhong:

  • Thuộc tính. Đầu tiên là kế thừa những thuộc tính từ lớp cơ sở PhuongTienGiaoThong. Tiếp đến là định nghĩa thêm 02 thuộc tính riêng biệt: soLuongCanh; soLuongQuat.
  • Phương thức. Đầu tiên là kế thừa trọn vẹn những phương thức get / set đối với những thuộc tính được đặc tả ở lớp cơ sở PhuongTienGiaoThong. Tiếp đến là định nghĩa các phương thức get / set đối với thuộc tính soLuongCanh; soLuongQuat.
  • Kế thừa và đặc tả lại phương thức gioiThieu(). Đây là một phương thức được sử dụng trong ví dụ về tính chất đa hình.

Chú ý rằng những đặc trưng này sẽ được kế thừa lại hoàn toàn từ những lớp dẫn xuất của PhuongTienDuongKhong trên cây gia phả.

Bước 4.

Chúng ta đặc tả những đặc trưng của class PhuongTienDuongThuy:

  • Thuộc tính. Đầu tiên là kế thừa những thuộc tính từ lớp cơ sở PhuongTienGiaoThong. Tiếp đến là định nghĩa thêm 0 thuộc tính riêng biệt: loaiBanhLai.
  • Phương thức. Đầu tiên là kế thừa trọn vẹn những phương thức get / set đối với những thuộc tính được đặc tả ở lớp cơ sở PhuongTienGiaoThong. Tiếp đến là định nghĩa các phương thức get / set đối với thuộc tính loaiBanhLai.
  • Kế thừa và đặc tả lại phương thức gioiThieu(). Đây là một phương thức được sử dụng trong ví dụ về tính chất đa hình.

Chú ý rằng những đặc trưng này sẽ được kế thừa lại hoàn toàn từ những lớp dẫn xuất của PhuongTienDuongThuy trên cây gia phả.

Bước 5.

Chúng ta đặc tả những đặc trưng của class Oto:

  • Thuộc tính. Kế thừa trọn vẹn những thuộc tính từ lớp cơ sở PhuongTienDuongBo.
  • Phương thức. Kế thừa và đặc tả lại phương thức gioiThieu(). Đây là một phương thức được sử dụng trong ví dụ về tính chất đa hình.

Bước 6.

Chúng ta đặc tả những đặc trưng của class XeMay:

  • Thuộc tính. Kế thừa trọn vẹn những thuộc tính từ lớp cơ sở PhuongTienDuongBo.
  • Phương thức. Kế thừa và đặc tả lại phương thức gioiThieu(). Đây là một phương thức được sử dụng trong ví dụ về tính chất đa hình.

Bước 7.

Chúng ta đặc tả những đặc trưng của class XeDap:

  • Thuộc tính. Kế thừa trọn vẹn những thuộc tính từ lớp cơ sở PhuongTienDuongBo.
  • Phương thức. Kế thừa và đặc tả lại phương thức gioiThieu(). Đây là một phương thức được sử dụng trong ví dụ về tính chất đa hình.

Bước 8.

Chúng ta đặc tả những đặc trưng của class MayBay:

  • Thuộc tính. Kế thừa trọn vẹn những thuộc tính từ lớp cơ sở PhuongTienDuongKhong.
  • Phương thức. Kế thừa và đặc tả lại phương thức gioiThieu(). Đây là một phương thức được sử dụng trong ví dụ về tính chất đa hình.

Bước 9.

Chúng ta đặc tả những đặc trưng của class KhinhKhiCau:

  • Thuộc tính. Kế thừa trọn vẹn những thuộc tính từ lớp cơ sở PhuongTienDuongKhong.
  • Phương thức. Kế thừa và đặc tả lại phương thức gioiThieu(). Đây là một phương thức được sử dụng trong ví dụ về tính chất đa hình.

Bước 10.

Chúng ta đặc tả những đặc trưng của class TauThuy:

  • Thuộc tính. Kế thừa trọn vẹn những thuộc tính từ lớp cơ sở PhuongTienDuongThuy.
  • Phương thức. Kế thừa và đặc tả lại phương thức gioiThieu(). Đây là một phương thức được sử dụng trong ví dụ về tính chất đa hình.

Bước 11.

Chúng ta đặc tả những đặc trưng của class Thuyen:

  • Thuộc tính. Kế thừa trọn vẹn những thuộc tính từ lớp cơ sở PhuongTienDuongThuy.
  • Phương thức. Kế thừa và đặc tả lại phương thức gioiThieu(). Đây là một phương thức được sử dụng trong ví dụ về tính chất đa hình.

Bước 12.

Chúng ta đặc tả những đặc trưng của class ThuyPhiCo:

  • Thuộc tính. Đầu tiên là kế thừa những thuộc tính từ lớp cơ sở PhuongTienGiaoThong. Tiếp đến là định nghĩa thêm 02 thuộc tính riêng biệt: loaiBanhLai; soLuongCanh.
  • Phương thức. Đầu tiên là kế thừa trọn vẹn những phương thức get / set đối với những thuộc tính được đặc tả ở lớp cơ sở PhuongTienGiaoThong. Tiếp đến là định nghĩa các phương thức get / set đối với thuộc tính loaiBanhLai; soLuongCanh.
  • Kế thừa và đặc tả lại phương thức gioiThieu(). Đây là một phương thức được sử dụng trong ví dụ về tính chất đa hình.

Bước 13.

Chúng ta thực hiện thử nghiệm tính đa hình như bên dưới.

Chúng ta có thể nhận thấy những điểm rất rõ ở đây là:

  • Thực thể của đối tượng nào thì sẽ tự biết mình là ai.
  • Và như vậy sẽ tự thực hiện một cách chính xác phương thức gioiThieu() cũng như các phương thức get / set của các thuộc tính được đặc tả trong lớp trừu tượng PhuongTienGiaoThong.

Bước 14.

Kết quả thực hiện thử nghiệm đa hình thứ nhất như sau:

Thiết kế Tính đa hình thứ hai

Bước 1.

Chúng ta định nghĩa phương thức trừu tượng thongBao() trong interface cơ sở HoatDong.

Bước 2.

Chúng ta định nghĩa interface CoTheChay kế thừa từ interface HoatDong:

  • Kế thừa việc định nghĩa các phương thức trừu tượng từ interface HoatDong.
  • Định nghĩa phương thức trừu tượng riêng biệt: chay().

Bước 3.

Chúng ta định nghĩa interface CoTheBoi kế thừa từ interface HoatDong:

  • Kế thừa việc định nghĩa các phương thức trừu tượng từ interface HoatDong.
  • Định nghĩa phương thức trừu tượng riêng biệt: boi().

Bước 4.

Chúng ta định nghĩa interface CoTheBay kế thừa từ interface HoatDong:

  • Kế thừa việc định nghĩa các phương thức trừu tượng từ interface HoatDong.
  • Định nghĩa phương thức trừu tượng riêng biệt: bay().

Bước 5.

Chúng ta điều chỉnh class PhuongTienDuongBo để thuộc phạm vi ảnh hưởng của interface CoTheChay:

  • Chúng ta sử dụng từ khóa implements, có nghĩa là thực thi một interface nào đó.
  • Kế thừa và đặc tả lại toàn bộ các phương thức trừu tượng được định nghĩa trong interface HoatDong cũng như CoTheChay.

Bước 6.

Chúng ta điều chỉnh class PhuongTienDuongThuy để thuộc phạm vi ảnh hưởng của interface CoTheBoi:

  • Chúng ta sử dụng từ khóa implements, có nghĩa là thực thi một interface nào đó.
  • Kế thừa và đặc tả lại toàn bộ các phương thức trừu tượng được định nghĩa trong interface HoatDong cũng như CoTheBoi.

Bước 7.

Chúng ta điều chỉnh class PhuongTienDuongKhong để thuộc phạm vi ảnh hưởng của interface CoTheBay:

  • Chúng ta sử dụng từ khóa implements, có nghĩa là thực thi một interface nào đó.
  • Kế thừa và đặc tả lại toàn bộ các phương thức trừu tượng được định nghĩa trong interface HoatDong cũng như CoTheBay.

Bước 8.

Chúng ta điều chỉnh class ThuyPhiCo để thuộc phạm vi ảnh hưởng của interface CoTheChayCoTheBoi.

  • Chúng ta sử dụng từ khóa implements, có nghĩa là thực thi một interface nào đó.
  • Có thể thực thi cùng lúc nhiều interface. Có nghĩa rằng 1 lớp đối tượng có thể cùng lúc chịu ảnh hưởng của nhiều bộ quy tắc khác nhau.
  • Kế thừa và đặc tả lại toàn bộ các phương thức trừu tượng được định nghĩa trong interface HoatDong cũng như CoTheChay, CoTheBoi.

Bước 9.

Chúng ta điều chỉnh class Oto:

Bước 10.

Chúng ta điều chỉnh class XeMay:

Bước 11.

Chúng ta điều chỉnh class XeDap:

Bước 12.

Chúng ta điều chỉnh class MayBay:

Bước 13.

Chúng ta điều chỉnh class KhinhKhiCau:

Bước 14.

Chúng ta điều chỉnh class TauThuy:

Bước 15.

Chúng ta điều chỉnh class Thuyen:

Bước 16.

Chúng ta điều chỉnh lại ví dụ về tính đa hình như bên dưới.

Những điểm cần chú ý:

  • Những đối tượng thuộc phạm vi ảnh hưởng của những interface khác nhau sẽ thực thi những phương thức đặc trưng riêng của từng interface.
  • Chúng ta cần kiểm tra một chút để biết thực thể của đối tượng nào bằng cách sử dụng từ khóa instanceof.

Bước 17.

Chúng ta chú ý thực hiện phương thức require_once theo:

  • Thứ tự sử dụng các classinterface.
  • Chú ý đặc điểm của PHP là sẽ sao chép toàn bộ mã nguồn của file php vào đúng vị trí thực hiện require_once nên chúng ta phải xem xét từng classinterface.
  • Trong từng classinterface, nếu có sử dụng đến class hay interface nào khác, nhằm mục đích kế thừa hoặc thực thi, thì phải thực hiện require_once đến class hay interface này trước.
  • Như vậy chúng ta lần lượt thực hiện require_once từ classinterface cơ sở, rồi xuống dần trên cây gia phả.

Tổng kết

Trong bài này, chúng ta đã cùng nhau tìm hiểu sự hỗ trợ của PHP trong việc thực hiện tính chất đa hình trong Lập trình hướng đối tượng.

Hi vọng với bài này thì chúng ta đã có cái nhìn tổng quát hơn về cả 04 tính chất đặc trưng nhất của Lập trình hướng đối tượng.

Lập trình hướng đối tượng – Phần 3 – Tính chất đa hình (polymorphism), lớp trừu tượng (abstract class) và giao diện (interface) – Csharp

Giới thiệu

Trong nội dung bài viết này, chúng ta cùng nhau tìm hiểu cách thức mà Java hỗ trợ việc thực hiện những thuật ngữ về Lập trình hướng đối tượng: (i) tính chất trừu tượng – abstraction; (ii) tính chất đa hình – polymorphism; (iii) lớp trừu tượng – abstract class; (iv) giao diện – interface.

Chúng ta thiết kế một chương trình nhỏ bao gồm các lớp và giao diện như sau:

  • Lớp trừu tượng: PhuongTienGiaoThong.
  • Các lớp đối tượng ở tầng dưới thứ hai: PhuongTienDuongBo; PhuongTienDuongThuy; PhuongTienDuongKhong.
  • Các lớp đối tượng ở tầng dưới cùng: Oto; XeMay; XeDap; TauThuy; Thuyen; MayBay; KhinhKhiCau; ThuyPhiCo.
  • Giao diện ở cấp cao nhất: HoatDong.
  • Giao diện ở tầng dưới: CoTheChay; CoTheBay; CoTheBoi.

Thiết kế Lớp trừu tượng

Bước 1.

Chúng ta thực hiện tạo Console Project trong MonoDevelop và đặt tên là CsharpOOPThirdProject.

Mặc định thì class Program.cs được tạo ra với phương thức Main().

Bước 2.

Chúng ta thực hiện tạo folder Object.

Chúng ta thực hiện tạo class PhuongTienGiaoThong.

Bước 3.

Chúng ta thực hiện tạo class PhuongTienDuongBo là một dẫn xuất của class PhuongTienGiaoThong.

Bước 4.

Chúng ta thực hiện tạo class PhuongTienDuongThuy là một dẫn xuất của class PhuongTienGiaoThong.

Bước 5.

Chúng ta thực hiện tạo class PhuongTienDuongKhong là một dẫn xuất của class PhuongTienGiaoThong.

Thiết kế Lớp đối tượng

Bước 1.

Chúng ta thực hiện tạo class Oto là một dẫn xuất của class PhuongTienDuongBo.

Bước 2.

Chúng ta thực hiện tạo class XeMay là một dẫn xuất của class PhuongTienDuongBo.

Bước 3.

Chúng ta thực hiện tạo class XeDap là một dẫn xuất của class PhuongTienDuongBo.

Bước 4.

Chúng ta thực hiện tạo class Thuyen là một dẫn xuất của class PhuongTienDuongThuy.

Bước 5.

Chúng ta thực hiện tạo class TauThuy là một dẫn xuất của class PhuongTienDuongThuy.

Bước 6.

Chúng ta thực hiện tạo class MayBay là một dẫn xuất của class PhuongTienDuongKhong.

Bước 7.

Chúng ta thực hiện tạo class KhinhKhiCau là một dẫn xuất của class PhuongTienDuongKhong.

Bước 8.

Chúng ta thực hiện tạo class ThuyPhiCo là một dẫn xuất của class PhuongTienGiaoThong.

Thiết kế Giao diện

Bước 1.

Chúng ta thực hiện tạo folder action.

Chúng ta thực hiện tạo interface ICoTheChay.

Những điểm cần chú ý:

  • Chúng ta sử dụng từ khóa interface đứng trước định nghĩa tên của giao diện.
  • Riêng đối với Csharp, một quy tắc phổ biến là thêm chữ cái I đứng trước tên dự kiến được đặt cho giao diện. Ở đây chúng ta có ICoTheChay.

Bước 2.

Chúng ta thực hiện tạo interface ICoTheBoi.

Bước 3.

Chúng ta thực hiện tạo interface ICoTheBay.

Bước 4.

Chúng ta thực hiện tạo interface IHoatDong là giao diện cơ sở của các giao diện: ICoTheChay; ICoTheBay; ICoTheBoi.

Thiết kế Tính đa hình thứ nhất

Bước 1.

Chúng ta đặc tả những đặc trưng của abstract class PhuongTienGiaoThong:

  • Thuộc tính: soLuongBanhXe; soLuongChoNgoi.
  • Những phương thức get / set.
  • Phương thức trừu tượng: GioiThieu().

Chú ý rằng những đặc trưng này sẽ được kế thừa lại hoàn toàn từ những lớp dẫn xuất của PhuongTienGiaoThong trên cây gia phả.

Bước 2.

Chúng ta đặc tả những đặc trưng của class PhuongTienDuongBo:

  • Thuộc tính. Đầu tiên là kế thừa những thuộc tính từ lớp cơ sở PhuongTienGiaoThong. Tiếp đến là định nghĩa thêm 01 thuộc tính riêng biệt: loaiDongCo.
  • Phương thức. Đầu tiên là kế thừa trọn vẹn những phương thức get / set đối với những thuộc tính được đặc tả ở lớp cơ sở PhuongTienGiaoThong. Tiếp đến là định nghĩa các phương thức get / set đối với thuộc tính loaiDongCo.
  • Kế thừa và đặc tả lại phương thức GioiThieu(). Đây là một phương thức được sử dụng trong ví dụ về tính chất đa hình.

Chú ý rằng những đặc trưng này sẽ được kế thừa lại hoàn toàn từ những lớp dẫn xuất của PhuongTienDuongBo trên cây gia phả.

Bước 3.

Chúng ta đặc tả những đặc trưng của class PhuongTienDuongKhong:

  • Thuộc tính. Đầu tiên là kế thừa những thuộc tính từ lớp cơ sở PhuongTienGiaoThong. Tiếp đến là định nghĩa thêm 02 thuộc tính riêng biệt: soLuongCanh; soLuongQuat.
  • Phương thức. Đầu tiên là kế thừa trọn vẹn những phương thức get / set đối với những thuộc tính được đặc tả ở lớp cơ sở PhuongTienGiaoThong. Tiếp đến là định nghĩa các phương thức get / set đối với thuộc tính soLuongCanh; soLuongQuat.
  • Kế thừa và đặc tả lại phương thức GioiThieu(). Đây là một phương thức được sử dụng trong ví dụ về tính chất đa hình.

Chú ý rằng những đặc trưng này sẽ được kế thừa lại hoàn toàn từ những lớp dẫn xuất của PhuongTienDuongKhong trên cây gia phả.

Bước 4.

Chúng ta đặc tả những đặc trưng của class PhuongTienDuongThuy:

  • Thuộc tính. Đầu tiên là kế thừa những thuộc tính từ lớp cơ sở PhuongTienGiaoThong. Tiếp đến là định nghĩa thêm 01 thuộc tính riêng biệt: loaiBanhLai.
  • Phương thức. Đầu tiên là kế thừa trọn vẹn những phương thức get / set đối với những thuộc tính được đặc tả ở lớp cơ sở PhuongTienGiaoThong. Tiếp đến là định nghĩa các phương thức get / set đối với thuộc tính loaiBanhLai.
  • Kế thừa và đặc tả lại phương thức GioiThieu(). Đây là một phương thức được sử dụng trong ví dụ về tính chất đa hình.

Chú ý rằng những đặc trưng này sẽ được kế thừa lại hoàn toàn từ những lớp dẫn xuất của PhuongTienDuongThuy trên cây gia phả.

Bước 5.

Chúng ta đặc tả những đặc trưng của class Oto:

  • Thuộc tính. Kế thừa trọn vẹn những thuộc tính từ lớp cơ sở PhuongTienDuongBo.
  • Phương thức. Kế thừa và đặc tả lại phương thức GioiThieu(). Đây là một phương thức được sử dụng trong ví dụ về tính chất đa hình.

Bước 6.

Chúng ta đặc tả những đặc trưng của class XeMay:

  • Thuộc tính. Kế thừa trọn vẹn những thuộc tính từ lớp cơ sở PhuongTienDuongBo.
  • Phương thức. Kế thừa và đặc tả lại phương thức GioiThieu(). Đây là một phương thức được sử dụng trong ví dụ về tính chất đa hình.

Bước 7.

Chúng ta đặc tả những đặc trưng của class XeDap:

  • Thuộc tính. Kế thừa trọn vẹn những thuộc tính từ lớp cơ sở PhuongTienDuongBo.
  • Phương thức. Kế thừa và đặc tả lại phương thức GioiThieu(). Đây là một phương thức được sử dụng trong ví dụ về tính chất đa hình.

Bước 8.

Chúng ta đặc tả những đặc trưng của class MayBay:

  • Thuộc tính. Kế thừa trọn vẹn những thuộc tính từ lớp cơ sở PhuongTienDuongKhong.
  • Phương thức. Kế thừa và đặc tả lại phương thức GioiThieu(). Đây là một phương thức được sử dụng trong ví dụ về tính chất đa hình.

Bước 9.

Chúng ta đặc tả những đặc trưng của class KhinhKhiCau:

  • Thuộc tính. Kế thừa trọn vẹn những thuộc tính từ lớp cơ sở PhuongTienDuongKhong.
  • Phương thức. Kế thừa và đặc tả lại phương thức GioiThieu(). Đây là một phương thức được sử dụng trong ví dụ về tính chất đa hình.

Bước 10.

Chúng ta đặc tả những đặc trưng của class TauThuy:

  • Thuộc tính. Kế thừa trọn vẹn những thuộc tính từ lớp cơ sở PhuongTienDuongThuy.
  • Phương thức. Kế thừa và đặc tả lại phương thức GioiThieu(). Đây là một phương thức được sử dụng trong ví dụ về tính chất đa hình.

Bước 11.

Chúng ta đặc tả những đặc trưng của class Thuyen:

  • Thuộc tính. Kế thừa trọn vẹn những thuộc tính từ lớp cơ sở PhuongTienDuongThuy.
  • Phương thức. Kế thừa và đặc tả lại phương thức GioiThieu(). Đây là một phương thức được sử dụng trong ví dụ về tính chất đa hình.

Bước 12.

Chúng ta đặc tả những đặc trưng của class ThuyPhiCo:

  • Thuộc tính. Đầu tiên là kế thừa những thuộc tính từ lớp cơ sở PhuongTienGiaoThong. Tiếp đến là định nghĩa thêm 02 thuộc tính riêng biệt: loaiBanhLai; soLuongCanh.
  • Phương thức. Đầu tiên là kế thừa trọn vẹn những phương thức get / set đối với những thuộc tính được đặc tả ở lớp cơ sở PhuongTienGiaoThong. Tiếp đến là định nghĩa các phương thức get / set đối với thuộc tính loaiBanhLai; soLuongCanh.
  • Kế thừa và đặc tả lại phương thức GioiThieu(). Đây là một phương thức được sử dụng trong ví dụ về tính chất đa hình.

Bước 13.

Chúng ta thực hiện thử nghiệm tính đa hình như bên dưới.

Chúng ta có thể nhận thấy những điểm rất rõ ở đây là:

  • Thực thể của đối tượng nào thì sẽ tự biết mình là ai.
  • Và như vậy sẽ tự thực hiện một cách chính xác phương thức GioiThieu() cũng như các phương thức get / set của các thuộc tính được đặc tả trong lớp trừu tượng PhuongTienGiaoThong.

Bước 14.

Kết quả thực hiện thử nghiệm đa hình thứ nhất như sau:

Thiết kế Tính đa hình thứ hai

Bước 1.

Chúng ta định nghĩa phương thức trừu tượng ThongBao() trong interface cơ sở IHoatDong.

Bước 2.

Chúng ta định nghĩa interface ICoTheChay kế thừa từ interface IHoatDong:

  • Kế thừa việc định nghĩa các phương thức trừu tượng từ interface IHoatDong.
  • Định nghĩa phương thức trừu tượng riêng biệt: Chay().

Bước 3.

Chúng ta định nghĩa interface ICoTheBoi kế thừa từ interface IHoatDong:

  • Kế thừa việc định nghĩa các phương thức trừu tượng từ interface IHoatDong.
  • Định nghĩa phương thức trừu tượng riêng biệt: Boi().

Bước 4.

Chúng ta định nghĩa interface ICoTheBay kế thừa từ interface IHoatDong:

  • Kế thừa việc định nghĩa các phương thức trừu tượng từ interface IHoatDong.
  • Định nghĩa phương thức trừu tượng riêng biệt: Bay().

Bước 5.

Chúng ta điều chỉnh class PhuongTienDuongBo để thuộc phạm vi ảnh hưởng của interface ICoTheChay:

  • Kế thừa và đặc tả lại toàn bộ các phương thức trừu tượng được định nghĩa trong interface IHoatDong cũng như ICoTheChay.

Bước 6.

Chúng ta điều chỉnh class PhuongTienDuongThuy để thuộc phạm vi ảnh hưởng của interface ICoTheBoi:

  • Kế thừa và đặc tả lại toàn bộ các phương thức trừu tượng được định nghĩa trong interface IHoatDong cũng như ICoTheBoi.

Bước 7.

Chúng ta điều chỉnh class PhuongTienDuongKhong để thuộc phạm vi ảnh hưởng của interface ICoTheBay:

  • Kế thừa và đặc tả lại toàn bộ các phương thức trừu tượng được định nghĩa trong interface IHoatDong cũng như ICoTheBay.

Bước 8.

Chúng ta điều chỉnh class ThuyPhiCo để thuộc phạm vi ảnh hưởng của interface ICoTheChayICoTheBoi.

  • Có thể thực thi cùng lúc nhiều interface. Có nghĩa rằng 1 lớp đối tượng có thể cùng lúc chịu ảnh hưởng của nhiều bộ quy tắc khác nhau.
  • Kế thừa và đặc tả lại toàn bộ các phương thức trừu tượng được định nghĩa trong interface IHoatDong cũng như ICoTheChay, ICoTheBoi.

Bước 9.

Chúng ta điều chỉnh lại ví dụ về tính đa hình như bên dưới.

Những điểm cần chú ý:

  • Những đối tượng thuộc phạm vi ảnh hưởng của những interface khác nhau sẽ thực thi những phương thức đặc trưng riêng của từng interface.
  • Chúng ta cần kiểm tra một chút để biết thực thể của đối tượng nào bằng cách sử dụng từ khóa is.

Tổng kết

Trong bài này, chúng ta đã cùng nhau tìm hiểu sự hỗ trợ của Csharp trong việc thực hiện tính chất đa hình trong Lập trình hướng đối tượng.

Hi vọng với bài này thì chúng ta đã có cái nhìn tổng quát hơn về cả 04 tính chất đặc trưng nhất của Lập trình hướng đối tượng.

Lập trình hướng đối tượng – Phần 3 – Tính chất đa hình (polymorphism), lớp trừu tượng (abstract class) và giao diện (interface) – Java

Giới thiệu

Trong nội dung bài viết này, chúng ta cùng nhau tìm hiểu cách thức mà Java hỗ trợ việc thực hiện những thuật ngữ về Lập trình hướng đối tượng: (i) tính chất trừu tượng – abstraction; (ii) tính chất đa hình – polymorphism; (iii) lớp trừu tượng – abstract class; (iv) giao diện – interface.

Chúng ta thiết kế một chương trình nhỏ bao gồm các lớp và giao diện như sau:

  • Lớp trừu tượng: PhuongTienGiaoThong.
  • Các lớp đối tượng ở tầng dưới thứ hai: PhuongTienDuongBo; PhuongTienDuongThuy; PhuongTienDuongKhong.
  • Các lớp đối tượng ở tầng dưới cùng: Oto; XeMay; XeDap; TauThuy; Thuyen; MayBay; KhinhKhiCau; ThuyPhiCo.
  • Giao diện ở cấp cao nhất: HoatDong.
  • Giao diện ở tầng dưới: CoTheChay; CoTheBay; CoTheBoi.

Thiết kế Lớp trừu tượng

Bước 1.

Chúng ta thực hiện tạo Java Project trong Eclipse IDE và đặt tên là JavaOOPThirdProject.

Chúng ta thực hiện tạo package mainclass Main.java với phương thức main() mặc định.

Bước 2.

Chúng ta thực hiện tạo package object.

Chúng ta thực hiện tạo class PhuongTienGiaoThong.

Những điểm cần chú ý:

  • Đây là một lớp trừu tượng, nên chúng ta sử dụng từ khóa abstract phía trước định nghĩa tên của class.

Bước 3.

Chúng ta thực hiện tạo class PhuongTienDuongBo là một dẫn xuất của class PhuongTienGiaoThong.

Bước 4.

Chúng ta thực hiện tạo class PhuongTienDuongThuy là một dẫn xuất của class PhuongTienGiaoThong.

Bước 5.

Chúng ta thực hiện tạo class PhuongTienDuongKhong là một dẫn xuất của class PhuongTienGiaoThong.

Thiết kế Lớp đối tượng

Bước 1.

Chúng ta thực hiện tạo class Oto là một dẫn xuất của class PhuongTienDuongBo.

Bước 2.

Chúng ta thực hiện tạo class XeMay là một dẫn xuất của class PhuongTienDuongBo.

Bước 3.

Chúng ta thực hiện tạo class XeDap là một dẫn xuất của class PhuongTienDuongBo.

Bước 4.

Chúng ta thực hiện tạo class Thuyen là một dẫn xuất của class PhuongTienDuongThuy.

Bước 5.

Chúng ta thực hiện tạo class TauThuy là một dẫn xuất của class PhuongTienDuongThuy.

Bước 6.

Chúng ta thực hiện tạo class MayBay là một dẫn xuất của class PhuongTienDuongKhong.

Bước 7.

Chúng ta thực hiện tạo class KhinhKhiCau là một dẫn xuất của class PhuongTienDuongKhong.

Bước 8.

Chúng ta thực hiện tạo class ThuyPhiCo là một dẫn xuất của class PhuongTienGiaoThong.

Thiết kế Giao diện

Bước 1.

Chúng ta thực hiện tạo package action.

Chúng ta thực hiện tạo interface CoTheChay.

Những điểm cần chú ý:

  • Chúng ta sử dụng từ khóa interface đứng trước định nghĩa tên của giao diện.

Bước 2.

Chúng ta thực hiện tạo interface CoTheBoi.

Bước 3.

Chúng ta thực hiện tạo interface CoTheBay.

Bước 4.

Chúng ta thực hiện tạo interface HoatDong là giao diện cơ sở của các giao diện: CoTheChay; CoTheBay; CoTheBoi.

Thiết kế Tính đa hình thứ nhất

Bước 1.

Chúng ta đặc tả những đặc trưng của abstract class PhuongTienGiaoThong:

  • Thuộc tính: soLuongBanhXe; soLuongChoNgoi.
  • Những phương thức get / set.
  • Phương thức trừu tượng: gioiThieu().

Chú ý rằng những đặc trưng này sẽ được kế thừa lại hoàn toàn từ những lớp dẫn xuất của PhuongTienGiaoThong trên cây gia phả.

Bước 2.

Chúng ta đặc tả những đặc trưng của class PhuongTienDuongBo:

  • Thuộc tính. Đầu tiên là kế thừa những thuộc tính từ lớp cơ sở PhuongTienGiaoThong. Tiếp đến là định nghĩa thêm 01 thuộc tính riêng biệt: loaiDongCo.
  • Phương thức. Đầu tiên là kế thừa trọn vẹn những phương thức get / set đối với những thuộc tính được đặc tả ở lớp cơ sở PhuongTienGiaoThong. Tiếp đến là định nghĩa các phương thức get / set đối với thuộc tính loaiDongCo.
  • Kế thừa và đặc tả lại phương thức gioiThieu(). Đây là một phương thức được sử dụng trong ví dụ về tính chất đa hình.

Chú ý rằng những đặc trưng này sẽ được kế thừa lại hoàn toàn từ những lớp dẫn xuất của PhuongTienDuongBo trên cây gia phả.

Bước 3.

Chúng ta đặc tả những đặc trưng của class PhuongTienDuongKhong:

  • Thuộc tính. Đầu tiên là kế thừa những thuộc tính từ lớp cơ sở PhuongTienGiaoThong. Tiếp đến là định nghĩa thêm 02 thuộc tính riêng biệt: soLuongCanh; soLuongQuat.
  • Phương thức. Đầu tiên là kế thừa trọn vẹn những phương thức get / set đối với những thuộc tính được đặc tả ở lớp cơ sở PhuongTienGiaoThong. Tiếp đến là định nghĩa các phương thức get / set đối với thuộc tính soLuongCanh; soLuongQuat.
  • Kế thừa và đặc tả lại phương thức gioiThieu(). Đây là một phương thức được sử dụng trong ví dụ về tính chất đa hình.

Chú ý rằng những đặc trưng này sẽ được kế thừa lại hoàn toàn từ những lớp dẫn xuất của PhuongTienDuongKhong trên cây gia phả.

Bước 4.

Chúng ta đặc tả những đặc trưng của class PhuongTienDuongThuy:

  • Thuộc tính. Đầu tiên là kế thừa những thuộc tính từ lớp cơ sở PhuongTienGiaoThong. Tiếp đến là định nghĩa thêm 0 thuộc tính riêng biệt: loaiBanhLai.
  • Phương thức. Đầu tiên là kế thừa trọn vẹn những phương thức get / set đối với những thuộc tính được đặc tả ở lớp cơ sở PhuongTienGiaoThong. Tiếp đến là định nghĩa các phương thức get / set đối với thuộc tính loaiBanhLai.
  • Kế thừa và đặc tả lại phương thức gioiThieu(). Đây là một phương thức được sử dụng trong ví dụ về tính chất đa hình.

Chú ý rằng những đặc trưng này sẽ được kế thừa lại hoàn toàn từ những lớp dẫn xuất của PhuongTienDuongThuy trên cây gia phả.

Bước 5.

Chúng ta đặc tả những đặc trưng của class Oto:

  • Thuộc tính. Kế thừa trọn vẹn những thuộc tính từ lớp cơ sở PhuongTienDuongBo.
  • Phương thức. Kế thừa và đặc tả lại phương thức gioiThieu(). Đây là một phương thức được sử dụng trong ví dụ về tính chất đa hình.

Bước 6.

Chúng ta đặc tả những đặc trưng của class XeMay:

  • Thuộc tính. Kế thừa trọn vẹn những thuộc tính từ lớp cơ sở PhuongTienDuongBo.
  • Phương thức. Kế thừa và đặc tả lại phương thức gioiThieu(). Đây là một phương thức được sử dụng trong ví dụ về tính chất đa hình.

Bước 7.

Chúng ta đặc tả những đặc trưng của class XeDap:

  • Thuộc tính. Kế thừa trọn vẹn những thuộc tính từ lớp cơ sở PhuongTienDuongBo.
  • Phương thức. Kế thừa và đặc tả lại phương thức gioiThieu(). Đây là một phương thức được sử dụng trong ví dụ về tính chất đa hình.

Bước 8.

Chúng ta đặc tả những đặc trưng của class MayBay:

  • Thuộc tính. Kế thừa trọn vẹn những thuộc tính từ lớp cơ sở PhuongTienDuongKhong.
  • Phương thức. Kế thừa và đặc tả lại phương thức gioiThieu(). Đây là một phương thức được sử dụng trong ví dụ về tính chất đa hình.

Bước 9.

Chúng ta đặc tả những đặc trưng của class KhinhKhiCau:

  • Thuộc tính. Kế thừa trọn vẹn những thuộc tính từ lớp cơ sở PhuongTienDuongKhong.
  • Phương thức. Kế thừa và đặc tả lại phương thức gioiThieu(). Đây là một phương thức được sử dụng trong ví dụ về tính chất đa hình.

Bước 10.

Chúng ta đặc tả những đặc trưng của class TauThuy:

  • Thuộc tính. Kế thừa trọn vẹn những thuộc tính từ lớp cơ sở PhuongTienDuongThuy.
  • Phương thức. Kế thừa và đặc tả lại phương thức gioiThieu(). Đây là một phương thức được sử dụng trong ví dụ về tính chất đa hình.

Bước 11.

Chúng ta đặc tả những đặc trưng của class Thuyen:

  • Thuộc tính. Kế thừa trọn vẹn những thuộc tính từ lớp cơ sở PhuongTienDuongThuy.
  • Phương thức. Kế thừa và đặc tả lại phương thức gioiThieu(). Đây là một phương thức được sử dụng trong ví dụ về tính chất đa hình.

Bước 12.

Chúng ta đặc tả những đặc trưng của class ThuyPhiCo:

  • Thuộc tính. Đầu tiên là kế thừa những thuộc tính từ lớp cơ sở PhuongTienGiaoThong. Tiếp đến là định nghĩa thêm 02 thuộc tính riêng biệt: loaiBanhLai; soLuongCanh.
  • Phương thức. Đầu tiên là kế thừa trọn vẹn những phương thức get / set đối với những thuộc tính được đặc tả ở lớp cơ sở PhuongTienGiaoThong. Tiếp đến là định nghĩa các phương thức get / set đối với thuộc tính loaiBanhLai; soLuongCanh.
  • Kế thừa và đặc tả lại phương thức gioiThieu(). Đây là một phương thức được sử dụng trong ví dụ về tính chất đa hình.

Bước 13.

Chúng ta thực hiện thử nghiệm tính đa hình như bên dưới.

Chúng ta có thể nhận thấy những điểm rất rõ ở đây là:

  • Thực thể của đối tượng nào thì sẽ tự biết mình là ai.
  • Và như vậy sẽ tự thực hiện một cách chính xác phương thức gioiThieu() cũng như các phương thức get / set của các thuộc tính được đặc tả trong lớp trừu tượng PhuongTienGiaoThong.

Bước 14.

Kết quả thực hiện thử nghiệm đa hình thứ nhất như sau:

Thiết kế Tính đa hình thứ hai

Bước 1.

Chúng ta định nghĩa phương thức trừu tượng thongBao() trong interface cơ sở HoatDong.

Bước 2.

Chúng ta định nghĩa interface CoTheChay kế thừa từ interface HoatDong:

  • Kế thừa việc định nghĩa các phương thức trừu tượng từ interface HoatDong.
  • Định nghĩa phương thức trừu tượng riêng biệt: chay().

Bước 3.

Chúng ta định nghĩa interface CoTheBoi kế thừa từ interface HoatDong:

  • Kế thừa việc định nghĩa các phương thức trừu tượng từ interface HoatDong.
  • Định nghĩa phương thức trừu tượng riêng biệt: boi().

Bước 4.

Chúng ta định nghĩa interface CoTheBay kế thừa từ interface HoatDong:

  • Kế thừa việc định nghĩa các phương thức trừu tượng từ interface HoatDong.
  • Định nghĩa phương thức trừu tượng riêng biệt: bay().

Bước 5.

Chúng ta điều chỉnh class PhuongTienDuongBo để thuộc phạm vi ảnh hưởng của interface CoTheChay:

  • Chúng ta sử dụng từ khóa implements, có nghĩa là thực thi một interface nào đó.
  • Kế thừa và đặc tả lại toàn bộ các phương thức trừu tượng được định nghĩa trong interface HoatDong cũng như CoTheChay.

Bước 6.

Chúng ta điều chỉnh class PhuongTienDuongThuy để thuộc phạm vi ảnh hưởng của interface CoTheBoi:

  • Chúng ta sử dụng từ khóa implements, có nghĩa là thực thi một interface nào đó.
  • Kế thừa và đặc tả lại toàn bộ các phương thức trừu tượng được định nghĩa trong interface HoatDong cũng như CoTheBoi.

Bước 7.

Chúng ta điều chỉnh class PhuongTienDuongKhong để thuộc phạm vi ảnh hưởng của interface CoTheBay:

  • Chúng ta sử dụng từ khóa implements, có nghĩa là thực thi một interface nào đó.
  • Kế thừa và đặc tả lại toàn bộ các phương thức trừu tượng được định nghĩa trong interface HoatDong cũng như CoTheBay.

Bước 8.

Chúng ta điều chỉnh class ThuyPhiCo để thuộc phạm vi ảnh hưởng của interface CoTheChayCoTheBoi.

  • Chúng ta sử dụng từ khóa implements, có nghĩa là thực thi một interface nào đó.
  • Có thể thực thi cùng lúc nhiều interface. Có nghĩa rằng 1 lớp đối tượng có thể cùng lúc chịu ảnh hưởng của nhiều bộ quy tắc khác nhau.
  • Kế thừa và đặc tả lại toàn bộ các phương thức trừu tượng được định nghĩa trong interface HoatDong cũng như CoTheChay, CoTheBoi.

Bước 9.

Chúng ta điều chỉnh lại ví dụ về tính đa hình như bên dưới.

Những điểm cần chú ý:

  • Những đối tượng thuộc phạm vi ảnh hưởng của những interface khác nhau sẽ thực thi những phương thức đặc trưng riêng của từng interface.
  • Chúng ta cần kiểm tra một chút để biết thực thể của đối tượng nào bằng cách sử dụng từ khóa instanceof.

Tổng kết

Trong bài này, chúng ta đã cùng nhau tìm hiểu sự hỗ trợ của Java trong việc thực hiện tính chất đa hình trong Lập trình hướng đối tượng.

Hi vọng với bài này thì chúng ta đã có cái nhìn tổng quát hơn về cả 04 tính chất đặc trưng nhất của Lập trình hướng đối tượng.

Lập trình hướng đối tượng – Phần 3 – Tính chất đa hình (polymorphism), lớp trừu tượng (abstract class) và giao diện (interface)

Giới thiệu

Trong nội dung bài này, chúng ta cùng nhau tìm hiểu về mặt lý thuyết cũng như ý nghĩa thực sự của những thuật ngữ sau trong Lập trình hướng đối tượng: (i) tính chất trừu tượng – abstraction; (ii) tính chất đa hình – polymorphism; (iii) lớp trừu tượng – abstract class; (iv) giao diện – interface.

Những nội dung này sẽ được trình bày theo định hướng tổng quát và độc lập ngôn ngữ nhất có thể.

Như vậy chúng ta dễ dàng hơn trong việc thiết kế kiến trúc các chương trình tùy theo ngôn ngữ lập trình đang sử dụng.

Tính chất đa hình

Trước tiên, chúng ta cùng nhắc lại định nghĩa cơ bản của 02 khái niệm có sự liên quan mật thiết với nhau.

Tính chất trừu tượng – abstraction:

Định nghĩa cơ bản và thông dụng nhất:

  • 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.

Trên đây là định nghĩa có vẻ rất lý thuyết và thực ra là không dễ hiểu một chút nào. Vậy chúng ta cùng nhau tìm hiểu một cách định nghĩa khác về tính chất trừu tượng.

Trừu tượng hóa là một tác vụ trong đó chúng ta định nghĩa (liệt kê) những thuộc tính (thông tin / đặc điểm) và phương thức (thao tác / hành động) mà tất cả các đối tượng trong cùng một nhóm đều sở hữu.

Chúng ta nhận thấy một số điểm cần chú ý trong định nghĩa trên:

  • Trừu tượng hóa là một tác vụ và được áp dụng cho một nhóm đối tượng cụ thể.
  • Những nội dung được liệt kê trong quá trình tác vụ hóa đều tồn tại trong tất cả các đối tượng trong nhóm.
  • Mở rộng từ tính chất kế thừa (inheritance), đương nhiên là tác vụ trừu tượng hóa cũng có nhiều tầng cấp độ.

Chúng ta xem xét một ví dụ cơ bản như sau.

Trước tiên, chúng ta có một nhóm các đối tượng: ô tô, xe máy, xe đạp, thuyền, tàu thủy, máy bay, khinh khí cầu.

Tiếp theo, chúng ta thực hiện trừu tượng hóa bằng cách liệt kê những nội dung chung nhất của tất cả các đối tượng trên:

  • Thuộc tính: số lượng bánh xe, số lượng chỗ ngồi.
  • Phương thức: tự giới thiệu.

Chúng ta có thể suy nghĩ để bổ sung thêm vào nhé.

Cuối cùng, chúng ta cũng có thể trừu tượng hóa ở cấp độ thấp hơn cho từng nhóm nhỏ các đối tượng trong nhóm lớn bên trên: nhóm đi đường bộ; nhóm đi đường thủy; nhóm đi đường không.

Tính đa hình – polymorphism

Định nghĩa cơ bản và thông dụng nhất:

  • 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.

Trên đây là định nghĩa có vẻ rất lý thuyết và thực ra là không dễ hiểu một chút nào. Vậy chúng ta cùng nhau tìm hiểu một cách định nghĩa khác về tính chất đa hình.

Trên thực tế, tính chất đa hình chính là một sự kết hợp và mở rộng giữa tính kế thừa và tính trừu tượng. Điều này có nghĩa rằng:

Những phương thức (thao tác / hành động) thuộc sở hữu chung sẽ được thực hiện theo cách riêng tùy theo vào đặc trưng của từng đối tượng trong cùng nhóm.

Chúng ta nhận thấy một số điểm cần chú ý trong định nghĩa trên:

  • Các phương thức thuộc sở hữu chung có thể được trừu tượng hóa hoặc không, nhưng nhất định phải được định nghĩa trước đó ở cấp độ cao hơn cấp độ của các đối tượng trong nhóm.
  • Mỗi đối tượng có thể kế thừa lại cách thức thực hiện phương thức ở cấp độ cao hơn hoặc tự định nghĩa lại cách thức thực hiện mới.
  • Kết quả trả về của phương thức có thể khác nhau nhưng kiểu trả về phải giống nhau.

Chúng ta xem xét 02 ví dụ cơ bản như sau.

Thứ nhất, đối với ví dụ về các nhóm đối tượng giao thông bên trên. Chúng ta thực hiện tính chất đa hình đối với phương thức tự_giới_thiệu.

  • Đối tượng ô tô có thể nói: Tôi là phương tiện ô tô.
  • Đối tượng máy bay có thể nói: Tôi là phương tiện máy bay.
  • Đối tượng tàu thủy có thể nói: Tôi là phương tiện tàu thủy.

Chúng ta có thể suy nghĩ để bổ sung thêm vào nhé.

Thứ hai, chúng ta có một đội hình gồm 11 cầu thủ bóng đá trong một đội.

Khi bước ra sân thi đấu, tất cả các cầu thủ đều có phương thức thi_đấu. Chúng ta có thể thực hiện tính chất đa hình với phương thức này như sau:

  • Thủ môn phải đẩy bóng.
  • Hậu vệ phải phá bóng và cản người.
  • Tiền vệ phải chuyền bóng.
  • Tiền đạo phải ghi bàn.

Chúng ta có thể suy nghĩ để bổ sung thêm vào nhé.

Lớp trừu tượng – abstract class

Chúng ta có thể hiểu một cách khái quát ở đây là lớp trừu tượng (abstract class) chính là một sự thể hiện của tính chất trừu tượng trong Lập trình hướng đối tượng.

Điều này có nghĩa rằng:

  • Một lớp trừu tượng đặc tả các thuộc tính và phương thức chung nhất của tất cả các lớp dẫn xuất được kế thừa từ nó.
  • Một phương thức trong lớp trừu tượng có thể: (i) được đặc tả là trừu tượng theo nghĩa là chỉ giới thiệu về tên gọi của thao tác / hành động; (ii) hoặc đặc tả luôn cách thức thực hiện thao tác / hành động này.
  • Một phương thức đã được đặc tả luôn cách thức thực hiện thì có thể được kế thừa lại hoàn toàn mà không cần đặc tả lại trong các lớp dẫn xuất nếu không có yêu cầu gì đặc biệt.
  • Một phương thức đã được đặc tả là trừu tượng thì phải được đặc tả lại trong tất cả các lớp dẫn xuất trực tiếp. Lúc này, phương thức này vẫn có thể tiếp tục được đặc tả là trừu tượng trong một lớp dẫn xuất nào đó trong trường hợp chúng ta xác định lớp dẫn xuất này sẽ trở thành lớp cơ sở của một số lớp đối tượng khác.

Chúng ta sẽ dần tìm hiểu sự hỗ trợ của từng ngôn ngữ lập trình trong việc đặc tả lớp trừu tượng trong các bài tiếp theo.

Giao diện (interface)

Về mặt lý thuyết, chúng ta có thể thấy rằng không có một định nghĩa cụ thể về thế nào là giao diện và tại sao lại phải có sự xuất hiện của giao diện trong Lập trình hướng đối tượng.

Như vậy chúng ta có thể đề xuất ra một định nghĩa giao diện như sau:

Một hình thức định nghĩa / liệt kê những phương thức (thao tác / hành động) theo cách trừu tượng hóa mà tất cả các đối tượng trong phạm vi ảnh hưởng đều phải hiện thực.

Chúng ta nhận thấy một số điểm cần chú ý trong định nghĩa trên:

  • Chúng ta có thể xem, ở một góc độ nào đó trong thực tế, giao diện giống như một bản danh sách các quy tắc / điều luật mà bắt buộc các đối tượng trong phạm vi ảnh hưởng phải tuân theo.
  • Các phương thức trong giao diện thì chỉ được đặc tả là trừu tượng theo nghĩa là chỉ giới thiệu về tên gọi của thao tác / hành động.
  • Không định nghĩa các thuộc tính vì không phải là đặc tả đối tượng hay nhóm đối tượng.
  • Những đối tượng trong phạm vi ảnh hưởng có thể cùng một nhóm hoặc không.
  • Từng đối tượng sẽ đặc tả lại các phương thức trong giao diện theo cách khác nhau.
  • Mở rộng từ tính chất kế thừa (inheritance), đương nhiên là giao diện và các tác vụ trừu tượng hóa cũng có nhiều tầng cấp độ.

Chúng ta có thể xem xét 01 ví dụ rất cơ bản và rõ ràng về các quy tắc mà có thể được định nghĩa trong các giao diện:

  • Ở cấp độ cao nhất, chúng ta có nội quy của một trường đại học.
  • Ở cấp độ thấp tiếp theo, chúng ta có nội quy của một phòng / ban / khoa.
  • Ở cấp độ thấp hơn nữa, chúng ta có nội quy của từng lớp học.

Chúng ta có những nhóm đối tượng khác nhau thuộc phạm vi ảnh hưởng bởi các nhóm quy tắc trên: Giảng viên; Cán bộ công nhân viên chức; Sinh viên; Học viên; …

Xác định phạm vi sử dụng lớp trừu tượng và giao diện

Nếu chúng ta xem xét lướt qua, có thể thấy rằng ý tưởng về lớp trừu tượng và giao diện là rất giống nhau. Thậm chí chúng ta có thể sử dụng một cách lẫn lộn giữa 02 hình thức này trong Lập trình hướng đối tượng vì đều có thể đáp ứng đầy đủ các tính chất: trừu tượng, kế thừa, đa hình.

Như vậy, câu hỏi đặt ra ở đây: Tại sao lại phải có sự xuất hiện đồng thời của cả 02 hình thức này trong Lập trình hướng đối tượng?

Câu trả lời ở đây là: Điều này thuộc vấn đề tư duy về lập trình hướng đối tượng.

Có nghĩa rằng: trong quá trình phân tích và thiết kế chương trình lập trình, chúng ta phải tự quyết định xem thuộc tính và phương thức nào thì nên được đặc tả trong một lớp đối tượng, và phương thức nào thì nên đặc tả trong một giao diện.

Chúng ta có thể tham khảo một số điểm để có thể giúp xác định chính xác hơn cho chương trình của mình:

  • Lớp trừu tượng thì đặc tả thuộc tính và phương thức chung (có thể trừu tượng hoặc không) của một nhóm đối tượng cụ thể; Giao diện thì chỉ đặc tả phương thức chung theo cách trừu tượng của các đối tượng thuộc nhiều nhóm khác nhau.
  • Một đối tượng thì chỉ kế thừa từ một lớp trừu tượng, nhưng có thể thuộc phạm vi ảnh hưởng của nhiều giao diện. Điều này cũng khá rõ ràng: một đối tượng thì chỉ thuộc một nhóm đối tượng theo chiều dọc, nhưng có thể phải tuân thủ nhiều nhóm quy tắc khác nhau theo chiều ngang.
  • Một đối tượng có thể kế thừa và hiện thực / định nghĩa lại cách thức thực hiện một số phương thức nào đó của lớp đối tượng, nhưng bắt buộc phải kế thừa và hiện thực / định nghĩa lại cách thức thực hiện toàn bộ các phương thức của giao diện.

Tổng kết

Trong bài này, chúng ta đã cùng nhau tìm hiểu về mặt lý thuyết cũng như ý nghĩa thực sự của những thuật ngữ sau trong Lập trình hướng đối tượng: (i) tính chất trừu tượng – abstraction; (ii) tính chất đa hình – polymorphism; (iii) lớp trừu tượng – abstract class; (iv) giao diện – interface.

Trong những bài tiếp theo, chúng ta sẽ tìm hiểu sự hỗ trợ việc hiện thực những thuật ngữ trên trong các ngôn ngữ lập trình Java / C# / Python / PHP là như thế nào.

Lập trình hướng đối tượng – Phần 2 – Tính chất kế thừa – PHP

Giới thiệu

Trong nội dung bài này, chúng ta cùng nhau tìm hiểu tính chất kế thừa trong tư duy Lập trình hướng đối tượng.

Chúng ta sẽ thử nghiệm tính chất này qua một ví dụ đơn giản về hình chữ nhật và hình vuông.

Nhắc lại đặc điểm của tính chất kế thừa như sau:

  • Đặ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.

Xây dựng lớp đối tượng HinhChuNhat

Bước 1.

Chúng ta tạo một PHP Project trong Eclipse IDE và đặt tên là PHPOOPSecondProject.

Chúng ta tiếp tục tạo file index.php.

Bước 2.

Chúng ta tạo folder objectclass HinhChuNhat.php.

Bước 3.

Chúng ta định nghĩa 02 thuộc tính cơ bản của một hình chữ nhật:

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 chất kế thừa, một lớp đối tượng có thể được kế thừa và mở rộng những thuộc tính và phương thức nào đó của lớp cơ sở.
  • Trong ví dụ ở đây, chúng ta đều biết rằng mỗi hình vuông đều là một hình chữ nhật và đều có 02 thuộc tính là chiều dài và chiều rộng. Do vậy chúng ta định nghĩa 02 thuộc tính của class HinhChuNhat theo cách mà có thể được kế thừa.
  • Chúng ta sử dụng từ khóa protected được PHP cung cấp. Từ khóa này quy định một thuộc tính hoặc một phương thức là ẩn, cho phép kế thừa và chỉ được truy xuất bên trong một lớp và những lớp con của nó.

Bước 4.

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

Bước 5.

Chúng ta định nghĩa các phương thức truy xuất và điều chỉnh dữ liệu, được gọi là các gettersetter:

Bước 6.

Chúng ta định nghĩa các phương thức tính chu vi, diện tích và đường chéo hình chữ nhật:

Những kỹ thuật lập trình cần chú ý:

Có lẽ cũng cần nhắc lại một chút về công thức tính đường chéo ở đây: (đường_chéo)^2 = (chiều_dài)^2 + (chiều_rộng)^2.

  • Kết quả của công thức tính đường chéo là một số thực có phần thập phân. Do vậy chúng ta sử dụng kiểu dữ liệu float do PHP cung cấp để đặc tả kết quả trả về này.

Xây dựng lớp đối tượng HinhVuong

Bước 1.

Chúng ta tạo class HinhVuong.php.

Những kỹ thuật lập trình cần chú ý:

  • Trong ví dụ ở đây, chúng ta sử dụng từ khóa extends do PHP cung cấp để đặc tả sự kế thừa.
  • Như đã mô tả ở trên về định nghĩa 02 thuộc tính chieuDaichieuRong. Chúng ta không cần định nghĩa lại 02 thuộc tính này trong class HinhVuong mà kế thừa từ HinhChuNhat.
  • Nếu phân tích theo một hướng khác, chúng ta có thể định nghĩa thuộc tính canh cho class HinhVuong. Như vậy thì nên thiết lập lại phạm vi là private cho 02 thuộc tính của class HinhChuNhat để không cho kế thừa.

Bước 2.

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ú ý:

  • Trong constructor cho class HinhVuong, chúng ta có thể thực thi tác vụ khởi tạo giá trị mặc định nào đó cho riêng class HinhVuong.
  • Nếu chúng ta muốn gọi constructor của lớp cơ sở để thực thi, ví dụ ở đây là class HinhChuNhat, chúng ta sử dụng phương thức parent và truyền tham số tương ứng với constructor cho class HinhChuNhat.

Bước 3.

Chúng ta thực hiện kế thừa và điều chỉnh phương thức setter:

Những kỹ thuật lập trình cần chú ý:

  • Thuật ngữ để kế thừa, điều chỉnh và mở rộng một phương thức của lớp cơ sở được gọi là nạp chồng hàm (override).
  • Trong ví dụ ở đây, chúng ta cần điều chỉnh phương thức setter vì trong hình vuông thì chiều dài và chiều rộng là bằng nhau (nên được gọi chung là cạnh).
  • Chú ý rằng chúng ta sử dụng phương thức parent để gọi đến setter đã được định nghĩa ở lớp cơ sở.

Bước 4.

Chúng ta thực hiện kế thừa và điều chỉnh phương thức tinhDuongCheo():

Những kỹ thuật lập trình cần chú ý:

  • Chúng ta không cần điều chỉnh các phương thức về tính chu vi và diện tích vì thực ra công thức là như nhau. Do vậy trong class HinhVuong chúng ta không đặc tả lại mà kế thừa hoàn toàn từ class HinhChuNhat đối với 02 phương thức tinhChuVi()tinhDienTich().
  • Đối với tác vụ tính đường chéo, chúng ta có 03 lựa chọn. Lựa chọn thứ nhất. Tương tự như 02 phương thức tinhChuVi()tinhDienTich(), chúng ta không đặc tả lại mà kế thừa hoàn toàn từ class HinhChuNhat. Lựa chọn thứ hai. Chúng ta thực hiện kế thừa lại bằng cách gọi phương thức của class HinhChuNhat để thực thi: parent::tinhDuongCheo(). Lựa chọn thứ ba. Chúng ta thực thi theo công thức thu gọn dành riêng cho hình vuông: (đường_chéo) ^2 = 2 * (cạnh)^2.

Thử nghiệm chương trình

Bước 1.

Chúng ta thực hiện thử nghiệm tạo mới 01 hình chữ nhật, 01 hình vuông và tính chu vi, diện tích, đường chéo:

Bước 2.

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 tính chất kế thừa trong 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ề tính chất kế thừa với ngôn ngữ PHP.

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.

Lập trình hướng đối tượng – Phần 2 – Tính chất kế thừa – Python

Giới thiệu

Trong nội dung bài này, chúng ta cùng nhau tìm hiểu tính chất kế thừa trong tư duy Lập trình hướng đối tượng.

Nhắc lại đặc điểm của tính chất kế thừa như sau:

  • Đặ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.

Xây dựng lớp đối tượng HinhChuNhat

Bước 1.

Chúng ta tạo một PyDev Project trong Eclipse IDE và đặt tên là PythonOOPSecondProject.

Chúng ta tiếp tục tạo package mainmodule Main.py cùng phương thức main() mặc định.

Bước 2.

Chúng ta tạo package objectmodule HinhChuNhat.py.

Bước 3.

Chúng ta định nghĩa 02 thuộc tính cơ bản của một hình chữ nhật:

Những kỹ thuật lập trình cần chú ý:

  • Chúng ta áp dụng cách tiếp cận định nghĩa hình thức properties bằng cách sử dụng decorator @property.
  • 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à do vậy cũng không thể định nghĩa tường minh việc kế thừa các thuộc tính.
  • Chúng ta sẽ hiện thực việc kế thừa các thuộc tính thông qua các properties trên.

Bước 4.

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

Bước 5.

Chúng ta định nghĩa các phương thức tính chu vi, diện tích và đường chéo hình chữ nhật:

Những kỹ thuật lập trình cần chú ý:

  • Có lẽ cũng cần nhắc lại một chút về công thức tính đường chéo ở đây: (đường_chéo)^2 = (chiều_dài)^2 + (chiều_rộng)^2.

Xây dựng lớp đối tượng HinhVuong

Bước 1.

Chúng ta tạo module HinhVuong.py.

Những kỹ thuật lập trình cần chú ý:

  • Trong ví dụ ở đây, chúng ta sử dụng cách thức của Python để đặc tả sự kế thừa: xác định tên của lớp cơ sở là class HinhChuNhat của module HinhChuNhat.py bên trong cặp dấu “()” bên cạnh tên của lớp dẫn xuất là class HinhVuong của module HinhVuong.py.
  • Chú ý rằng trong mỗi module abc.py, chúng ta có thể định nghĩa nhiều class khác nhau. Chúng ta được khuyến khích là mỗi module abc.py chỉ nên định nghĩa một class để dễ quản lý, và tốt nhất là trùng tên với module.

Bước 2.

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

Những kỹ thuật lập trình cần chú ý:

  • Trong constructor cho class HinhVuong, chúng ta có thể thực thi các tác vụ khởi tạo giá trị mặc định nào đó cho riêng class HinhVuong.
  • Nếu chúng ta muốn gọi constructor của lớp cơ sở để thực thi, ví dụ ở đây là class HinhChuNhat, chúng ta sử dụng phương thức super() và truyền tham số tương ứng với constructor cho class HinhChuNhat.

Bước 3.

Chúng ta thực hiện kế thừa và điều chỉnh phương thức setter:

Những kỹ thuật lập trình cần chú ý:

  • Trong ví dụ ở đây, chúng ta cần điều chỉnh phương thức setter vì trong hình vuông thì chiều dài và chiều rộng là bằng nhau (nên được gọi chung là cạnh).
  • Cú pháp để thực hiện kế thừa, mở rộng và điều chỉnh properties được thể hiện rõ nét trong ví dụ này. Chúng ta chỉ cần áp dụng tương tự cho những bài tập khác.
  • Chú ý rằng chúng ta sử dụng tên của lớp cơ sở, ở đây là HinhChuNhat, để gọi đến properties đã được định nghĩa ở lớp cơ sở. Sau đó chúng ta gọi đến phương thức fset() để thực hiện điều chỉnh thông tin.

Bước 4.

Chúng ta thực hiện kế thừa và điều chỉnh phương thức tinhDuongCheo():

Những kỹ thuật lập trình cần chú ý:

  • Chúng ta không cần điều chỉnh các phương thức về tính chu vi và diện tích vì thực ra công thức là như nhau. Do vậy trong class HinhVuong chúng ta không đặc tả lại mà kế thừa hoàn toàn từ class HinhChuNhat đối với 02 phương thức tinhChuVi()tinhDienTich().
  • Đối với tác vụ tính đường chéo, chúng ta có 03 lựa chọn. Lựa chọn thứ nhất. Tương tự như 02 phương thức tinhChuVi()tinhDienTich(), chúng ta không đặc tả lại mà kế thừa hoàn toàn từ class HinhChuNhat. Lựa chọn thứ hai. Chúng ta thực hiện kế thừa lại bằng cách gọi phương thức của class HinhChuNhat để thực thi: super().tinhDuongCheo(). Lựa chọn thứ ba. Chúng ta thực thi theo công thức thu gọn dành riêng cho hình vuông: (đường_chéo) ^2 = 2 * (cạnh)^2.

Thử nghiệm chương trình

Bước 1.

Chúng ta thực hiện thử nghiệm tạo mới 01 hình chữ nhật, 02 hình vuông và tính chu vi, diện tích, đường chéo:

Bước 2.

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 tính chất kế thừa trong 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ề tính chất kế thừa 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.

Lập trình hướng đối tượng – Phần 2 – Tính chất kế thừa – Csharp

Giới thiệu

Trong nội dung bài này, chúng ta cùng nhau tìm hiểu tính chất kế thừa trong tư duy Lập trình hướng đối tượng.

Chúng ta sẽ thử nghiệm tính chất này qua một ví dụ đơn giản về hình chữ nhật và hình vuông.

Nhắc lại đặc điểm của tính chất kế thừa như sau:

  • Đặ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.

Xây dựng lớp đối tượng HinhChuNhat

Bước 1.

Chúng ta tạo một Console Project trong MonoDevelop và đặt tên là CsharpOOPSecondProject.

Mặc định thì class Program.cs trong namespace CsharpOOPSecondProject với phương thức Main() được tạo ra.

Bước 2.

Chúng ta tạo class HinhChuNhat.cs và điều chỉnh namespace Object.

Bước 3.

Chúng ta định nghĩa 02 thuộc tính cơ bản của một hình chữ nhật:

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 chất kế thừa, một lớp đối tượng có thể được kế thừa và mở rộng những thuộc tính và phương thức nào đó của lớp cơ sở.
  • Trong ví dụ ở đây, chúng ta đều biết rằng mỗi hình vuông đều là một hình chữ nhật và đều có 02 thuộc tính là chiều dài và chiều rộng. Do vậy chúng ta định nghĩa 02 thuộc tính của class HinhChuNhat theo cách mà có thể được kế thừa.
  • Chúng ta sử dụng từ khóa protected được Csharp cung cấp. Từ khóa này quy định một thuộc tính hoặc một phương thức là ẩn, cho phép kế thừa và chỉ được truy xuất bên trong một lớp và những lớp con của nó.

Bước 4.

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

Bước 5.

Chúng ta định nghĩa các phương thức đặc biệt truy xuất và điều chỉnh dữ liệu, được gọi là các properties với gettersetter:

Những kỹ thuật lập trình cần chú ý:

  • Chúng ta biết rằng mỗi hình vuông là một hình chữ nhật đặc biệt trong đó chiều dài và chiều rộng là bằng nhau (nên được gọi chung là cạnh). Do vậy trong ví dụ ở đây, chúng ta sẽ cần kế thừa, mở rộng và điều chỉnh setter của properties ChieuDaiChieuRong.
  • Trước tiên, đối với phương thức ở lớp cơ sở mà dự kiến sẽ được kế thừa, mở rộng và điều chỉnh, chúng ta sử dụng từ khóa virtual do Csharp cung cấp.

Bước 6.

Chúng ta định nghĩa các phương thức tính chu vi, diện tích và đường chéo hình chữ nhật:

Những kỹ thuật lập trình cần chú ý:

  • Có lẽ cũng cần nhắc lại một chút về công thức tính đường chéo ở đây: (đường_chéo)^2 = (chiều_dài)^2 + (chiều_rộng)^2.
  • Kết quả của công thức tính đường chéo là một số thực có phần thập phân. Do vậy chúng ta sử dụng kiểu dữ liệu float hoặc double do Csharp cung cấp để đặc tả kết quả trả về này.
  • Tương tự như setter của properties ChieuDaiChieuRong, chúng ta có thể có nhu cầu kế thừa, mở rộng và điều chỉnh phương thức TinhDuongCheo() trong class HinhVuong. Do vậy chúng ta sử dụng từ khóa virtual ở đây.

Xây dựng lớp đối tượng HinhVuong

Bước 1.

Chúng ta tạo class HinhVuong.cs.

Những kỹ thuật lập trình cần chú ý:

  • Trong ví dụ ở đây, chúng ta sử dụng ký hiệu “:” phân tách giữa hai lớp để đặc tả sự kế thừa.
  • Như đã mô tả ở trên về định nghĩa 02 thuộc tính chieuDaichieuRong. Chúng ta không cần định nghĩa lại 02 thuộc tính này trong class HinhVuong mà kế thừa từ HinhChuNhat.
  • Nếu phân tích theo một hướng khác, chúng ta có thể định nghĩa thuộc tính canh cho class HinhVuong. Như vậy thì nên thiết lập lại phạm vi là private cho 02 thuộc tính của class HinhChuNhat để không cho kế thừa.

Bước 2.

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

Những kỹ thuật lập trình cần chú ý:

  • Chúng ta định nghĩa 02 constructor cho class HinhVuong tương ứng với 02 constructor cho class HinhChuNhat.
  • Trong từng constructor cho class HinhVuong, chúng ta có thể thực thi các tác vụ khởi tạo giá trị mặc định nào đó cho riêng class HinhVuong.
  • Nếu chúng ta muốn gọi constructor của lớp cơ sở để thực thi, ví dụ ở đây là class HinhChuNhat, chúng ta sử dụng phương thức base() và truyền tham số tương ứng với từng constructor cho class HinhChuNhat.

Bước 3.

Chúng ta thực hiện kế thừa và điều chỉnh phương thức setter:

Những kỹ thuật lập trình cần chú ý:

  • Thuật ngữ để kế thừa, điều chỉnh và mở rộng một phương thức của lớp cơ sở được gọi là nạp chồng hàm (override). Csharp cung cấp một kiểu từ khóa override để đặc tả một phương thức như vậy trong lớp dẫn xuất.
  • Trong ví dụ ở đây, chúng ta cần điều chỉnh phương thức setter vì trong hình vuông thì chiều dài và chiều rộng là bằng nhau (nên được gọi chung là cạnh).
  • Cú pháp để thực hiện kế thừa, mở rộng và điều chỉnh properties được thể hiện rõ nét trong ví dụ này. Chúng ta chỉ cần áp dụng tương tự cho những bài tập khác.
  • Chú ý rằng chúng ta sử dụng phương thức base để gọi đến properties đã được định nghĩa ở lớp dẫn xuất.

Bước 4.

Chúng ta thực hiện kế thừa và điều chỉnh phương thức TinhDuongCheo():

Những kỹ thuật lập trình cần chú ý:

  • Chúng ta không cần điều chỉnh các phương thức về tính chu vi và diện tích vì thực ra công thức là như nhau. Do vậy trong class HinhVuong chúng ta không đặc tả lại mà kế thừa hoàn toàn từ class HinhChuNhat đối với 02 phương thức TinhChuVi()TinhDienTich().
  • Đối với tác vụ tính đường chéo, chúng ta có 03 lựa chọn. Lựa chọn thứ nhất. Tương tự như 02 phương thức TinhChuVi()TinhDienTich(), chúng ta không đặc tả lại mà kế thừa hoàn toàn từ class HinhChuNhat. Lựa chọn thứ hai. Chúng ta thực hiện kế thừa lại với từ khóa override nhưng sẽ gọi phương thức của class HinhChuNhat để thực thi: base.TinhDuongCheo(). Lựa chọn thứ ba. Chúng ta thực thi theo công thức thu gọn dành riêng cho hình vuông: (đường_chéo) ^2 = 2 * (cạnh)^2.

Thử nghiệm chương trình

Bước 1.

Chúng ta thực hiện thử nghiệm tạo mới 01 hình chữ nhật, 02 hình vuông và tính chu vi, diện tích, đường chéo:

Những kỹ thuật lập trình cần chú ý:

  • Đối với việc khởi tạo một đối tượng hình vuông. Chúng ta có 02 sự lựa chọn: (i) HinhChuNhat hinhVuong = new HinhVuong(); (ii) HinhVuong hinhVuong = new HinhVuong(). Thực ra cả 02 sự lựa chọn này là như nhau vì class HinhVuong là lớp dẫn xuất của lớp cơ sở class HinhChuNhat.
  • Chúng ta được khuyến khích là áp dụng sự lựa chọn thứ nhất như trong ví dụ ở đây. Lý do chính là để hiểu rõ hơn về tính chất trừu tượng và đa hình của Lập trình hướng đối tượng mà sẽ được trao đổi kỹ hơn trong các bài tiếp theo.

Bước 2.

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 tính chất kế thừa trong 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ề tính chất kế thừa với ngôn ngữ Csharp.

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.

Lập trình hướng đối tượng – Phần 2 – Tính chất kế thừa – Java

Giới thiệu

Trong nội dung bài này, chúng ta cùng nhau tìm hiểu tính chất kế thừa trong tư duy Lập trình hướng đối tượng.

Chúng ta sẽ thử nghiệm tính chất này qua một ví dụ đơn giản về hình chữ nhật và hình vuông.

Nhắc lại đặc điểm của tính chất kế thừa như sau:

  • Đặ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.

Xây dựng lớp đối tượng HinhChuNhat

Bước 1.

Chúng ta tạo một Java Project trong Eclipse IDE và đặt tên là JavaOOPSecondProject.

Chúng ta tiếp tục tạo package mainclass Main.java cùng phương thức main() mặc định.

Bước 2.

Chúng ta tạo package objectclass HinhChuNhat.java.

Bước 3.

Chúng ta định nghĩa 02 thuộc tính cơ bản của một hình chữ nhật:

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 chất kế thừa, một lớp đối tượng có thể được kế thừa và mở rộng những thuộc tính và phương thức nào đó của lớp cơ sở.
  • Trong ví dụ ở đây, chúng ta đều biết rằng mỗi hình vuông đều là một hình chữ nhật và đều có 02 thuộc tính là chiều dài và chiều rộng. Do vậy chúng ta định nghĩa 02 thuộc tính của class HinhChuNhat theo cách mà có thể được kế thừa.
  • Chúng ta sử dụng từ khóa protected được Java cung cấp. Thuộc tính này quy định một thuộc tính hoặc một phương thức là ẩn, cho phép kế thừa và chỉ được truy xuất bên trong một lớp và những lớp con của nó.

Bước 4.

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

Bước 5.

Chúng ta định nghĩa các phương thức truy xuất và điều chỉnh dữ liệu, được gọi là các gettersetter:

Bước 6.

Chúng ta định nghĩa các phương thức tính chu vi, diện tích và đường chéo hình chữ nhật:

Những kỹ thuật lập trình cần chú ý:

  • Có lẽ cũng cần nhắc lại một chút về công thức tính đường chéo ở đây: (đường_chéo)^2 = (chiều_dài)^2 + (chiều_rộng)^2.
  • Kết quả của công thức tính đường chéo là một số thực có phần thập phân. Do vậy chúng ta sử dụng kiểu dữ liệu float hoặc double do Java cung cấp để đặc tả kết quả trả về này.

Xây dựng lớp đối tượng HinhVuong

Bước 1.

Chúng ta tạo class HinhVuong.java.

Những kỹ thuật lập trình cần chú ý:

  • Trong ví dụ ở đây, chúng ta sử dụng từ khóa extends do Java cung cấp để đặc tả sự kế thừa.
  • Như đã mô tả ở trên về định nghĩa 02 thuộc tính chieuDaichieuRong. Chúng ta không cần định nghĩa lại 02 thuộc tính này trong class HinhVuong mà kế thừa từ HinhChuNhat.
  • Nếu phân tích theo một hướng khác, chúng ta có thể định nghĩa thuộc tính canh cho class HinhVuong. Như vậy thì nên thiết lập lại phạm vi là private cho 02 thuộc tính của class HinhChuNhat để không cho kế thừa.

Bước 2.

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

Những kỹ thuật lập trình cần chú ý:

  • Chúng ta định nghĩa 02 constructor cho class HinhVuong tương ứng với 02 constructor cho class HinhChuNhat.
  • Trong từng constructor cho class HinhVuong, chúng ta có thể thực thi các tác vụ khởi tạo giá trị mặc định nào đó cho riêng class HinhVuong.
  • Nếu chúng ta muốn gọi constructor của lớp cơ sở để thực thi, ví dụ ở đây là class HinhChuNhat, chúng ta sử dụng phương thức super() và truyền tham số tương ứng với từng constructor cho class HinhChuNhat.

Bước 3.

Chúng ta thực hiện kế thừa và điều chỉnh phương thức setter:

Những kỹ thuật lập trình cần chú ý:

  • Thuật ngữ để kế thừa, điều chỉnh và mở rộng một phương thức của lớp cơ sở được gọi là nạp chồng hàm (override). Java cung cấp một kiểu chú thích (annotation) là @Override để đặc tả một phương thức như vậy trong lớp dẫn xuất.
  • Trong ví dụ ở đây, chúng ta cần điều chỉnh phương thức setter vì trong hình vuông thì chiều dài và chiều rộng là bằng nhau (nên được gọi chung là cạnh).

Bước 4.

Chúng ta thực hiện kế thừa và điều chỉnh phương thức tinhDuongCheo():

Những kỹ thuật lập trình cần chú ý:

  • Chúng ta không cần điều chỉnh các phương thức về tính chu vi và diện tích vì thực ra công thức là như nhau. Do vậy trong class HinhVuong chúng ta không đặc tả lại mà kế thừa hoàn toàn từ class HinhChuNhat đối với 02 phương thức tinhChuVi()tinhDienTich().
  • Đối với tác vụ tính đường chéo, chúng ta có 03 lựa chọn. Lựa chọn thứ nhất. Tương tự như 02 phương thức tinhChuVi()tinhDienTich(), chúng ta không đặc tả lại mà kế thừa hoàn toàn từ class HinhChuNhat. Lựa chọn thứ hai. Chúng ta thực hiện kế thừa lại bằng annotation @Override nhưng sẽ gọi phương thức của class HinhChuNhat để thực thi: super.tinhDuongCheo(). Lựa chọn thứ ba. Chúng ta thực thi theo công thức thu gọn dành riêng cho hình vuông: (đường_chéo) ^2 = 2 * (cạnh)^2.

Thử nghiệm chương trình

Bước 1.

Chúng ta thực hiện thử nghiệm tạo mới 01 hình chữ nhật, 02 hình vuông và tính chu vi, diện tích, đường chéo:

Những kỹ thuật lập trình cần chú ý:

  • Đối với việc khởi tạo một đối tượng hình vuông. Chúng ta có 02 sự lựa chọn: (i) HinhChuNhat hinhVuong = new HinhVuong(); (ii) HinhVuong hinhVuong = new HinhVuong(). Thực ra cả 02 sự lựa chọn này là như nhau vì class HinhVuong là lớp dẫn xuất của lớp cơ sở class HinhChuNhat.
  • Chúng ta được khuyến khích là áp dụng sự lựa chọn thứ nhất như trong ví dụ ở đây. Lý do chính là để hiểu rõ hơn về tính chất trừu tượng và đa hình của Lập trình hướng đối tượng mà sẽ được trao đổi kỹ hơn trong các bài tiếp theo.

Bước 2.

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 tính chất kế thừa trong 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ề tính chất kế thừa với ngôn ngữ Java.

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.

Lập trình hướng đối tượng – Phần 1 – Cơ bản về lớp đối tượng – PHP

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ữ PHP.

Bước 1.

Chúng ta tạo một PHP Project trong Eclipse IDE và đặt tên là PHPOOPFirstProject.

Chúng ta tiếp tục tạo file index.php.

Bước 2.

Chúng ta tạo folder objectclass HinhChuNhat.php.

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 folder có 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 đó.
  • PHP 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 class vào bên trong một folder hay 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ác class vào trong những folder theo tư duy hướng đối tượng.
  • Trong ví dụ hiện tại, chúng ta có thể đặt tên folderobject (nghĩa là đối tượng nói chung) hoặc shape (nghĩa là hình vẽ nói chung).

Bước 3.

Chúng ta định nghĩa 02 thuộc tính cơ bản của một hình chữ nhật:

Những kỹ thuật lập trình cần chú ý:

  • Như đã trình bày ở phần Giới thiệu về đặc trưng của một lớp đối tượng. Các thuộc tính nội tại của một đối tượng thì chỉ có thể được trông thấy và điều chỉnh bởi các phương thức nội tại của chính đối tượng đó.
  • Chúng ta sử dụng từ khóa private được PHP cung cấp. Thuộc tính này quy định một thuộc tính hoặc một phương thức là ẩn bên trong một lớp.

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ú ý:

  • Constructor là 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#, PHP chỉ cung cấp một phương thức constructor duy nhất là __construct(). Chúng ta sẽ chủ động quyết định xem có để tham số cho constructor hay không. Ngoài ra chúng ta chỉ có thể tạo duy nhất một dạng constructor có hoặc không có tham số. Đối với những phương thức khác, chúng ta sẽ tiếp tục tìm hiểu nội dung này trong những bài tiếp theo về lập trình hướng đối tượng.
  • Từ khóa this giú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.

Bước 5.

Chúng ta định nghĩa các phương thức truy xuất và điều chỉnh dữ liệu, được gọi là các gettersetter:

Những kỹ thuật lập trình cần chú ý:

  • Đây chính là những phương thức nội tại được dành riêng để truy xuất và điều chỉnh thông tin cho các thuộc tính nội tại.
  • Theo quy tắc chung, tên của các phương thức này nên để getset đứng trước tên của thuộc tính.
  • Mỗi thuộc tính nên được theo kèm bởi một cặp get / set.

Bước 6.

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 7.

Chúng ta thực hiện thử nghiệm tạo mới 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 một file php ở một folder khác, chúng ta sử dụng từ khóa require_once. Ví dụ ở đây là require_once ‘object/HinhChuNhat.php’. Khác với nhóm ngôn ngữ Java / C# / Python, cách thức thực hiện của PHP là sẽ sao chép toàn bộ mã nguồn của file vào đúng vị trí sử dụng require_once. Trên thực tế chúng ta có thể sử dụng từ khóa require. Nhưng như vậy có thể xảy ra trường hợp một file được truy xuất nhiều lần và có thể gây ra những hệ quả không mong muốn. Do vậy khuyến khích nên dùng require_once để chỉ truy xuất một lần duy nhất.
  • Chúng ta khởi tạo một đối tượng thực bằng cách gọi constructor của lớp đối tượng với toán tử new. Với constructor được gọi thì thuộc tính nội tại sẽ được khởi tạo với giá trị mặc định của nó.

Bước 8.

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ữ PHP.

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.