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 main và file 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
abstractphía trước định nghĩa tên củaclass.
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ứcget/setđối với thuộc tínhloaiDongCo.
- 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ứcget/setđối với thuộc tínhsoLuongCanh;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ứcget/setđối với thuộc tínhloaiBanhLai.
- 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ứcget/setđối với thuộc tínhloaiBanhLai;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ứcget/setcủa các thuộc tính được đặc tả trong lớp trừu tượngPhuongTienGiaoThong.

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ộtinterfacenà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 HoatDongcũ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ộtinterfacenà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 HoatDongcũ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ộtinterfacenà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 HoatDongcũ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 CoTheChay và CoTheBoi.
- Chúng ta sử dụng từ khóa
implements, có nghĩa là thực thi mộtinterfacenà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 HoatDongcũ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
interfacekhác nhau sẽ thực thi những phương thức đặc trưng riêng của từnginterface.
- 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
classvàinterface.
- Chú ý đặc điểm của PHP là sẽ sao chép toàn bộ mã nguồn của
file phpvào đúng vị trí thực hiệnrequire_oncenên chúng ta phải xem xét từngclassvàinterface.
- Trong từng
classvàinterface, nếu có sử dụng đếnclasshayinterfacenào khác, nhằm mục đích kế thừa hoặc thực thi, thì phải thực hiệnrequire_onceđếnclasshayinterfacenày trước.
- Như vậy chúng ta lần lượt thực hiện
require_oncetừclassvàinterfacecơ 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.