1. Tính kế thừa là gì?

Tính kế thừa trong lập trình hướng đối tượng là khả năng tạo một lớp mới dựa trên một lớp đã có sẵn từ trước. Lớp có sẵn là lớp cha, lớp mới là lớp con. Lớp con sẽ có tất cả các thuộc tính và phương thức của lớp cha. Ngoài ra nó cũng có thể có các phương thức và thuộc tính riêng của nó.

Lớp con sẽ kế thừa tất cả các thuộc tính và phương thức public và protected từ lớp cha(ta sẽ học public và protected kỹ hơn ở bài sau).

Tính kế thừa là một trong bốn tính chất của hướng đối tượng là: kế thừa, đóng gói, trừu tượng và đa hình. Nó đòi hỏi một chút sự tư duy logic để phân tích các đối tượng trong phần mềm để từ đó đưa ra mô hình giúp việc nâng cấp bảo trì trở nên dễ dàng hơn.

Ví dụ: Giả sử ta có 2 lớp động vật và con bò. Ta sẽ có bảng sau

Động vật Con bò
Thuộc tính:

  • Miệng
  • Mũi
  • Mắt
  • Tai
  • Chân
  • Giới tính

Phương thức:

  • Ăn
  • Ngủ
  • Chạy
Thuộc tính:

  • Miệng
  • Mũi
  • Mắt
  • Tai
  • Chân
  • Sừng

Phương thức:

  • Ăn
  • Ngủ
  • Cày

Ta có thể hiểu theo cách tự nhiên là con bò chính là thuộc nhóm động vật nhưng nó khác ở chỗ là nó có sừng và có thể đi cày. Và hiểu theo cách lập trình là lớp con bò đang kế thừa thuộc tính và phương thức của lớp động vật và nó cũng có những phương thức và thuộc tính khác lớp động vật.

Và nếu khai báo trong code ta sẽ có:

// Lớp Cha
class DongVat
{
    // Thuộc Tính
    var $mat = '';
    var $mui = '';
    var $mieng = '';
    var $chan = '';
    var $gioitinh = '';
  
    // Hàm, phương thức
    function an(){
        // lệnh
    }
  
    function ngu(){
        // lệnh
    }
  
    function chay(){
        // lệnh
    }
  
    function lahet(){
        // lệnh
    }
}
  
// Lớp Con
class ConBo extends DongVat {
  
    // Tất cả các thuộc tính khác đều kế thừa từ cha
    // nên không cần viết lại
    // chỉ riêng thuộc tính này là cha ko có nên ta phải khai báo
    var $cay = '';
  
    // Tất cả các hàm, phương thức đều kế thừa từ cha
    // nên không cần viết lại
}

Và để lớp kế thừa được xác định ta sẽ dùng từ khóa extends như trong ví dụ trên.

Chú ý

Ta cũng có thể thực hiện việc kế thừa bắc cầu. Nó có thể kết thừa được tất cả các thuộc tính từ lớp cha nó và lớp cha của lớp cha nó…

2. Gọi thuộc tính và phương thức của lớp cha trong hướng đối tượng PHP

2.1. Gọi bên trong lớp con

Do lớp con kế thừa thuộc tính và phương thức của lớp cha nên cách gọi cũng giống cách gọi các thuộc tính và phương thức của nó. Ta dùng từ khóa $this->thuoctinh, $this->phuong_thuc(). Tuy nhiên để phân biệt rõ ràng giữa thuộc tính và phương thức của cha và con, người ta sẽ dùng từ khóa parent::thuoctinh, parent::phuong_thuc() để gọi cha.

Ví dụ:

<strong>/ Lớp Động Vật
class DongVat
{
    // Thuộc tính
    var $mat = '';
    var $mui = '';
  
    // Phương Thức
    function an()
    {
        echo 'Dong Vat Dang An';
    }
}
  
// Lớp Con Bò
class ConBo extends DongVat
{
    function gioi_thieu()
    {
        $this->mat = 'Đây là cái mặt';
        $this->mui = 'Đây là cái mũi';
        parent::an(); // xuất ra chuỗi "Động Vật Đang Ăn"
    }
}</strong>

2.2. Gọi bên ngoài lớp con

Cũng tương tự như gọi bên trong lớp con ta sẽ dùng từ khóa $this->thuoctinh, $this->phuong_thuc() Tuy nhiên ta sẽ không sử dụng được cách sẽ dùng từ khóa parent::thuoctinh, parent::phuong_thuc() để gọi cha.

Ví dụ:

// Lớp Động Vật
class DongVat
{
    // Thuộc tính
    var $mat = '';
    var $mui = '';
  
    // Phương Thức
    function an()
    {
        echo 'Dong Vat Dang An';
    }
}
  
// Lớp Con Bò
class ConBo extends DongVat
{
    function gioi_thieu()
    {
        $this->mat = 'Đây là cái mặt';
        $this->mui = 'Đây là cái mũi';
        parent::an(); // xuất ra chuỗi "Động Vật Đang Ăn"
    }
}
  
// Chương Trình
$conbo = new ConBo();
  
// Gọi đến hàm gioi_thieu trong lớp Con Bò
// nên xuất ra màn hình chuỗi "Động Vật Đang Ăn"
$conbo->gioi_thieu();
  
// Trong hàm giới thiệu có gán giá trị cho 2
// thuộc tính mắt và mũi, giờ ta xuất ra màn hình
// xem giá trị nó là gì
  
echo $conbo->mat;
echo $conbo->mui;

3. Ngăn lớp kế thừa

Sau khi học về kế thừa ta cũng biết làm thế nào để ngăn việc kế thừa. Ta sẽ dùng từ khóa final.

Ví dụ:

<?php
class Fruit {
  final public function intro() {
    // some code
  }
}

class Strawberry extends Fruit {
  // sẽ dẫn đến lỗi
  public function intro() {
    // some code
  }
}
?>