Tính kế thừa chia lớp thành hai loại:

  1. Lớp dẫn xuất (lớp con) (derived class): lớp kế thừa từ lớp khác
  2. Lớp cơ sở (lớp cha mẹ) (base class): lớp cho lớp khác được kế thừa

1/ Khai báo kế thừa

Khai báo kế thừa sử dụng dấu hai chấm :

class Ten_lop_dan_xuat : chi_dinh_truy_cap Ten_lop_co_so
  • chi_dinh_truy_cap: chỉ định truy cập cho lớp cơ sở là public, private hoặc protected

Ví dụ

#include <iostream>
#include <string>
using namespace std;

// Lop co so (Base class)
class TraiCay {
  public: 
    string ten = "Xoai";
    void getTen() {
      cout << " Ten trai cay: " << ten ;
    }
};

// Lop dan xuat (Derived class)
class XuatKhau: public TraiCay {
  public: 
    string xuatXu = "Viet Nam";
};

int main() {
  cout << "THONG TIN SAN PHAM XUAT KHAU";
  cout << " \n";
  
  XuatKhau traiCay;
  traiCay.getTen();
  
  cout << " \n";
  cout << " Xuat xu: " << traiCay.xuatXu;
  return 0;
}
THONG TIN SAN PHAM XUAT KHAU 
 Ten trai cay: Xoai 
 Xuat xu: Viet Nam

Trong ví dụ này:

  • TraiCay (lớp trái cây) là lớp cơ sở,
  • XuatKhau (lớp xuất khẩu) là lớp dẫn xuất
  • XuatKhau kế thừa tất cả phương thức và thuộc tính của TraiCay

Tính kế thừa hữu ích cho việc tận dụng lại mã, "Không lặp lại chính mình" (DRY - Don't Repeat Yourself):
có thể sử dụng lại các thuộc tính và phương thức của một lớp hiện có khi các em tạo một lớp mới.

2/ Kế thừa nhiều cấp

Một lớp cũng có thể được dẫn xuất từ ​​một lớp mà lớp này đã được dẫn xuất từ ​​một lớp khác.

Ví dụ

#include <iostream>
#include <string>
using namespace std;

// Lop co so (Base class)
class TraiCay {
  public: 
    string ten = "Xoai";
    void getTen() {
      cout << " Ten trai cay: " << ten ;
    }
};

// Lop dan xuat (Derived class)
class XuatKhau: public TraiCay {
  public: 
    string xuatXu = "Viet Nam";
};

// Lop dan xuat (Derived class)
class HuuCo: public XuatKhau {
  public: 
    string loai = "Huu co";
};

int main() {
  cout << "THONG TIN SAN PHAM XUAT KHAU";
  cout << " \n";
  
  HuuCo traiCay;
  traiCay.getTen();
  
  cout << " \n";
  cout << " Xuat xu: " << traiCay.xuatXu;
  cout << " \n";
  cout << " Loai: " << traiCay.loai;
  return 0;
}
THONG TIN SAN PHAM XUAT KHAU 
 Ten trai cay: Xoai 
 Xuat xu: Viet Nam 
 Loai: Huu co

Trong ví dụ trên, lớp XuatKhau kế thừa từ lớp TraiCay, lớp HuuCo lại kế thừa từ lớp XuatKhau

3/ Kế thừa từ nhiều lớp

Một lớp có thể được dẫn xuất từ ​​nhiều hơn một lớp cơ sở, các lớp cơ sở cách nhau bằng dấu phẩy ,

Ví dụ

#include <iostream>
#include <string>
using namespace std;

// Lop co so (Base class)
class TraiCay {
  public: 
    string ten = "Xoai";
    void getTen() {
      cout << " Ten trai cay: " << ten ;
    }
};

// Lop co so (Base class)
class KhoLuuTru {
  public: 
    string viTri = "Kho so 8";
};

// Lop dan xuat (Derived class)
class XuatKhau: public TraiCay, public KhoLuuTru {
  public: 
    string xuatXu = "Viet Nam";
};

int main() {
  cout << "THONG TIN SAN PHAM XUAT KHAU";
  cout << " \n";
  
  XuatKhau traiCay;
  traiCay.getTen();
  
  cout << " \n";
  cout << " Xuat xu: " << traiCay.xuatXu;
  cout << " \n";
  cout << " Kho chua: " << traiCay.viTri;
  return 0;
}
THONG TIN SAN PHAM XUAT KHAU 
 Ten trai cay: Xoai 
 Xuat xu: Viet Nam 
 Kho chua: Kho so 8

Trong ví dụ trên, lớp XuatKhau kế thừa từ hai lớp TraiCayKhoLuuTru

4/ Chỉ định truy cập

Các em đã học về chỉ định truy cập publicprivate (Tính đóng gói của lớp trong C++) ở các bài trước, trong phần này các em sẽ học về chỉ định truy cập protected, nó tương tự như private, nhưng nó có thể được truy cập trong lớp dẫn xuất.

Ví dụ 1

#include <iostream>
#include <string>
using namespace std;

// Lop co so (Base class)
class TraiCay {
  protected: 
    string ten = "Xoai";
    void getTen() {
      cout << " Ten trai cay: " << ten ;
    }
};

// Lop dan xuat (Derived class)
class XuatKhau: public TraiCay {
  public: 
    string xuatXu = "Viet Nam";
};

int main() {
  cout << "THONG TIN SAN PHAM XUAT KHAU";
  cout << " \n";
  
  XuatKhau traiCay;
  traiCay.getTen();
  
  cout << " \n";
  cout << " Xuat xu: " << traiCay.xuatXu;
  return 0;
}

Kết quả

error: ‘void TraiCay::getTen()’ is protected within this context

Khi chạy chương trình, sẽ báo lỗi vì dòng số 7, chỉ định truy cập đang là protected cho thuộc tính ten và phương thức getTen() nên không thể truy cập từ bên ngoài lớp, tại đây thì protected giống với private.

Ví dụ 2

#include <iostream>
#include <string>
using namespace std;

// Lop co so (Base class)
class TraiCay {
  protected: 
    string ten = "Xoai";
};

// Lop dan xuat (Derived class)
class XuatKhau: public TraiCay {
  public: 
    string xuatXu = "Viet Nam";
    void getTen() {
      cout << " Ten trai cay: " << ten ;
    }
};

int main() {
  cout << "THONG TIN SAN PHAM XUAT KHAU";
  cout << " \n";
  
  XuatKhau traiCay;
  traiCay.getTen();
  
  cout << " \n";
  cout << " Xuat xu: " << traiCay.xuatXu;
  return 0;
}

Kết quả

THONG TIN SAN PHAM XUAT KHAU 
 Ten trai cay: Xoai 
 Xuat xu: Viet Nam

Như vậy chỉ định truy cập là protected có thể truy cập trong lớp dẫn xuất.

Các em thử thay dòng 7 của Ví dụ 2 thành private: để so sánh nhé