Hướng Dẫn Đầu Bạn Về Thừa Kế Trong C++

Xin chào các nhà phát triển C++ tương lai! Hôm nay, chúng ta sẽ bắt đầu hành trình hấp dẫn vào thế giới thừa kế của C++. Đừng lo nếu bạn là người mới bắt đầu với lập trình - tôi sẽ là người hướng dẫn bạn, và chúng ta sẽ làm theo từng bước một. Khi hết hướng dẫn này, bạn sẽ ngạc nhiên về mức độ học được của mình!

C++ Inheritance

Thừa Kế Là Gì?

Trước khi bước vào, hãy bắt đầu với một so sánh đơn giản. Hãy tưởng tượng bạn đang tạo một cây gia phả. Giống như con cái kế thừa các đặc điểm từ cha mẹ, trong C++, các lớp có thể kế thừa các thuộc tính và hành vi từ các lớp khác. Cool, phải không?

Thừa kế là một khái niệm cơ bản trong lập trình hướng đối tượng cho phép chúng ta tạo ra các lớp mới dựa trên các lớp hiện có. Điều này khuyến khích sử dụng lại mã và giúp tổ chức mã của chúng ta theo cấu trúc hệ thống.

Lớp Cơ Sở Và Lớp Đề Xuất

Trong thế giới thừa kế của C++, chúng ta có hai nhân vật chính: lớp cơ sở và lớp đề xuất.

Lớp Cơ Sở

Lớp cơ sở (cũng được gọi là lớp cha hoặc lớp mẹ) là lớp mà các lớp khác kế thừa. Nó như là tổ tiên trong cây gia phả mà chúng ta đã so sánh.

Hãy tạo một lớp cơ sở đơn giản:

class DongVat {
public:
void an() {
cout << "Con vật này đang ăn." << endl;
}

void ngu() {
cout << "Con vật này đang ngủ." << endl;
}
};

Trong ví dụ này, DongVat là lớp cơ sở của chúng ta. Nó có hai phương thức: an()ngu(). Đây là các hành vi phổ biến mà hầu hết các loài động vật có.

Lớp Đề Xuất

Lớp đề xuất (cũng được gọi là lớp con hoặc lớp con trẻ) là lớp mà kế thừa từ lớp cơ sở. Nó như là các cháu trong cây gia phả của chúng ta.

Hãy tạo một lớp đề xuất:

class Cho : public DongVat {
public:
void gau() {
cout << "Gâu! Gâu!" << endl;
}
};

Ở đây, Cho là lớp đề xuất của chúng ta. Nó kế thừa từ DongVat, vì vậy nó tự động có các phương thức an()ngu(). Chúng ta cũng đã thêm một phương thức mới gau() mà chỉ thuộc về chú chó.

Bây giờ, hãy xem cách chúng ta có thể sử dụng các lớp này:

int main() {
Cho myCho;
myCho.an();   // Output: Con vật này đang ăn.
myCho.ngu();  // Output: Con vật này đang ngủ.
myCho.gau();  // Output: Gâu! Gâu!
return 0;
}

Có phải là tuyệt vời không? Lớp Cho của chúng ta có thể sử dụng các phương thức từ lớp DongVat mà không cần chúng ta phải viết lại chúng!

Quyền Truy Cập Và Thừa Kế

Bây giờ, hãy nói về ai có thể thấy gì trong gia đình C++ của chúng ta. Giống như trong các gia đình thực tế, một số điều là công khai, một số chỉ cho gia đình và một số là bí mật cá nhân.

Trong C++, chúng ta có ba mức truy cập:

  1. Công khai
  2. Bảo vệ
  3. Riêng tư

Hãy xem cách các mức truy cập này hoạt động với thừa kế:

class DongVat {
public:
int tuoi;
protected:
string ten;
private:
int maBíMật;
};

class Cho : public DongVat {
public:
void setTen(string n) {
ten = n;  // OK, 'ten' được bảo vệ trong DongVat
}
void setMaBíMật(int code) {
// maBíMật = code;  // Lỗi! 'maBíMật' là riêng tư trong DongVat
}
};

Trong ví dụ này:

  • tuoi là công khai, vì vậy nó có thể được truy cập từ bất kỳ nơi nào.
  • ten được bảo vệ, vì vậy nó có thể được truy cập trong DongVat và bất kỳ lớp đề xuất nào từ DongVat.
  • maBíMật là riêng tư, vì vậy nó chỉ có thể được truy cập trong lớp DongVat.

Các Loại Thừa Kế

C++ cung cấp nhiều loại thừa kế khác nhau để phù hợp với nhiều nhu cầu khác nhau. Hãy khám phá chúng!

Thừa Kế Đơn

Đây là dạng đơn giản nhất, khi một lớp kế thừa từ một lớp cơ sở duy nhất. Chúng ta đã đã thấy điều này với ví dụ Cho.

Thừa Kế Đa Cấp

Đây như một dòng gia tộc: con cháu kế thừa từ cha, cha kế thừa từ ông.

class DongVat {
public:
void an() { cout << "Đang ăn..." << endl; }
};

class ThucVat : public DongVat {
public:
void thoi() { cout << "Đang thở..." << endl; }
};

class Cho : public ThucVat {
public:
void gau() { cout << "Đang gâu..." << endl; }
};

int main() {
Cho myCho;
myCho.an();    // Từ DongVat
myCho.thoi();  // Từ ThucVat
myCho.gau();   // Từ Cho
return 0;
}

Thừa Kế Hệ Thống

Đây là khi nhiều lớp kế thừa từ một lớp cơ sở duy nhất. Như là các anh em trong một gia đình.

class DongVat {
public:
void an() { cout << "Đang ăn..." << endl; }
};

class Cho : public DongVat {
public:
void gau() { cout << "Đang gâu..." << endl; }
};

class Meo : public DongVat {
public:
void meo() { cout << "Đang mèo..." << endl; }
};

Thừa Kế Đa

Thừa kế đa là khi một lớp kế thừa từ nhiều lớp cơ sở hơn. Như có các đặc điểm từ cả cha mẹ!

class SinhVatBay {
public:
void bay() { cout << "Đang bay..." << endl; }
};

class SinhVatBoi {
public:
void boi() { cout << "Đang bơi..." << endl; }
};

class Vịt : public SinhVatBay, public SinhVatBoi {
public:
void quack() { cout << "Đang quắc..." << endl; }
};

int main() {
Vịt myVit;
myVit.bay();    // Từ SinhVatBay
myVit.boi();    // Từ SinhVatBoi
myVit.quack();  // Từ Vịt
return 0;
}

Nhưng hãy cẩn thận! Thừa kế đa có thể dẫn đến tình trạng nổi tiếng "kim cương" nếu không sử dụng cẩn thận.

Bảng Phương Pháp Thừa Kế

Dưới đây là bảng tóm tắt các phương pháp thừa kế mà chúng ta đã thảo luận:

Loại Thừa Kế Mô Tả Ví Dụ
Đơn Một lớp kế thừa từ một lớp cơ sở Cho : public DongVat
Đa Cấp Một lớp kế thừa từ một lớp đề xuất Cho : public ThucVat, ThucVat : public DongVat
Hệ Thống Nhiều lớp kế thừa từ một lớp cơ sở Cho : public DongVat, Meo : public DongVat
Đa Một lớp kế thừa từ nhiều lớp cơ sở Vịt : public SinhVatBay, public SinhVatBoi

Và đó là tất cả, các bạn! Chúng ta đã bắt đầu với các khái niệm cơ bản về thừa kế trong C++. Hãy nhớ, luyện tập sẽ làm bạn hoàn hảo, vì vậy đừng sợ thử nghiệm với các khái niệm này. Chúc các bạn có những giờ lập trình vui vẻ, và may mắn thừa kế luôn ở bên cạnh bạn!

Credits: Image by storyset