[BÀI 31] KẾ THỪA TRONG PHP

Kế thừa là gì:

Kế thừa trong php được hiểu là class này có thể sử dụng lại các thuộc tính, phương thức của class khác mà không cần viết lại từ đầu. Mỗi thuộc tính, phương thức chỉ cần viết một lần duy nhất và có thể chia sẻ thông tin với class khác nhờ sự kế thừa.

Class cho các class khác kế thừa được gọi là class cha, class được kế thừa gọi là class con. Ngôn ngữ PHP cho phép đa kế thừa, tức là class A có thể kế thừa từ class B, class B có thể kế thừa từ class C….

Khi class A kế thừa từ class B, class A sẽ có tất cả các thuộc tính, phương thức của class B, ngoài ra class A còn có thể có các phương thức, thuộc tính mới hoặc loại bỏ đi một số thuộc tính, phương thức của class B. Tôi gọi đây là kế thừa có chọn lọc. Class A chỉ lấy những cái mình cần từ class B, và tạo nên các thuộc tính mới, phương thức mới, thể hiện cá tính và chức năng của mình.

Không phải class nào cũng cho class khác kế thừa, để quy định điều này chúng ta sử dụng các từ khóa mà PHP đã định sẵn.

Cú pháp kế thừa trong PHP:

class A extends class B{…}

Trong đó “extends” là từ khóa khai báo có sự kế thừa.

Tôi lấy một ví dụ đơn giản tôi có class xe, class xe là class quản lý chung tất cả các loại xe (xe đạp, xe máy, ô tô,…) ,class xe chứa các đặc điểm chung mà tất cả các loại xe đều có, như là bánh xe, màu sắc, vận tốc. Và tôi có 1 class là xe máy kế thừa từ class xe, tôi không cần viết lại bánh xe, màu sắc, và vận tốc nữa, và có thể dùng luôn những thứ đã khai báo ở class xe.

Trong class “xemay” tôi không khai báo phương thức nào hết, nhưng lúc gọi hàm tôi vẫn gọi được, lý do là class “xemay” đã được kế thừa từ class “xe” và có tất cả những gì class “xe” có.

Nạp chồng:

Nạp chồng sử dụng khi class con muốn thay đổi các thuộc tính, phương thức của lớp cha. Như ví dụ ở trên, tôi có in ra vận tốc của xe máy thì sẽ in ra vận tốc là 2000km/h. bây giờ tôi muốn sửa lại vận tốc này. Tôi phải nạp chồng (ghi đè) lại phương thức vận tốc bằng cách tạo 1 function mới trong class con có tên trùng với function muốn ghi đè ở lớp cha.

Có thể thấy là tôi đã viết một hàm có tên là vận tốc (vantoc), ở class con và hàm này trùng tên với 1 hàm có trong class cha. Do vậy mà vận tốc của xe máy bây giờ là 9000 chứ không phải 2000 như trước nữa.

Trong trường hợp tôi muốn khai báo thêm thuộc tính, phương thức ở class con nhưng vẫn sử dụng những cái ở class cha, lúc này tôi sử dụng từ khóa parent để thực thi thuộc tính/phương thức ở class cha, sau đó tôi ghi thêm những thuộc tính, phương thức mà class con có. Ví dụ:

Class xe máy đã lấy được nội dung của phương thức vantoc() ở class cha và khai báo thêm một thuộc tính mới, thể hiện đặc tính riêng biệt của xe máy để có thể phân biệt với các loại xe khác.

Không cho class khác kế thừa:

Một số class bạn không muốn các class khác kế thừa thì chỉ cần thêm từ khóa final ở ngay trước. Ví dụ:

final class xe(){…}

final function vantoc(){…}

Tại sao phải chống kế thừa: khi kế thừa, thì class con có khả năng thay đổi,bổ sung lại nội dung của class cha. Những file như file kết nối database (có lưu mật khẩu, tài khoản,…). Chúng ta phải chống kế thừa, tránh việc tài khoản mật khẩu bị thay đổi.

Lớp Abstract trong PHP:

Abstract là một lớp trừu tượng.

Lớp trừu tượng là lớp chứa các thuộc tính/phương thức trừu tượng.

Lớp trừu tượng, thuộc tính trừu tượng, phương thức trừu tượng bắt đầu bằng từ khóa abstract.

Thuộc tính/phương thức trừu tượng là các thuộc tính/phương thức không rõ ràng, chúng chỉ được khai báo tên, mà chưa được định nghĩa rõ ràng (là các thuộc tính/phương thức rỗng). Ví dụ tôi chắc chắn rằng ở biển Nha Trang sẽ có đặc sản riêng, chắc chắn sẽ có đặc sản nhưng tôi không biết chính xác đặc sản ở Nha Trang có những gì, và chúng như thế nào. Tôi khai báo một phương thức chung chung (phương thức trừu tượng) là đặc sản, phương thức này tôi không ghi gì hết. Và việc của những người đã từng ở Nha Trang là họ biết các đặc sản ở đây và họ sẽ thực hiện quảng cáo đặc sản của họ. Tức là họ tiến hành mô tả chi tiết các đặc sản của họ. Hay đơn giản là họ định nghĩa lại thuộc tính/phương thức trừu tượng mà tôi đã khai báo.

Abstract cũng là một class cho các class khác kế thừa. Song có một đặc điểm quan trọng mà chúng ta cần lưu ý đó là ở lớp Abstract sẽ có các thuộc tính/phương thức bắt buộc class con của nó phải đi định nghĩa lại. Chẳng hạn như xe phải có bánh xe, nếu không có bánh xe sẽ tạo nên lỗi. Class cha sẽ khai báo phương thức trừu tượng là bánh xe, và class con bắt buộc phải đi định nghĩa lại phương thức bánh xe này. Mỗi class con sẽ có một phương thức bánh xe khác nhau, do vậy tạo nên các đặc tính riêng biệt của các loại xe. Chẳng hạn, bánh xe máy sẽ khác bánh xe đạp sẽ khác bánh xe ô tô.

Lớp Abstract: ngoài việc chứa các thuộc tính/phương thức trửu tượng còn có thể có các thuộc tính/phương thức bình thường.

Lớp con kế thừa từ lớp abstract cũng sử dụng từ khóa extends.

Ví dụ: tôi bắt buộc tất cả các loại xe đều phải có bánh xe, và như ví dụ sau, trong class con tôi không định nghĩa lại phương thức trừu tượng bánh xe thì sẽ xảy ra lỗi:

Để không xảy ra lỗi, bắt buộc tôi phải đi định nghĩa lại phương thức banhxe() ở class con:

Lớp interface trong php:

Về bản chất lớp interface cũng là một lớp có khả năng cho lớp khác kếthừa. Khác với abstract, lớp interface không được phép có các thuộc tính/phương thức bình thường.

Lớp con của lớp interface cũng bắt buộc phải định nghĩa lại các thuộc tính/phương thức của class cha. Nếu không định nghĩa lại sẽ gặp lỗi.

Lớp con kế thừa từ lớp cha không sử dụng từ khóa extends mà dùng từ khóa implements.

Ví dụ:

Khai báo sau sẽ gặp lỗi khi class con không định nghĩa lại phương thức/thuộc tính của interface:

Khai báo sau sẽ không xảy ra lỗi vì class con đã định nghĩa lại các phương thức có trong lớp interface:

Xem video hướng dẫn về kế thừa trong PHP: