Menu
CoddyTech

Kế thừa cơ bản

Thuộc phần Lập trình hướng đối tượng trong hành trình C++ của Coddy. Bài học 48 trên 104.

Kế thừa (inheritance) cho phép một lớp có các thuộc tính và hành vi của một lớp khác. Lớp được kế thừa gọi là lớp cơ sở (hoặc lớp cha), còn lớp kế thừa gọi là lớp dẫn xuất (hoặc lớp con).

Để tạo lớp dẫn xuất, hãy dùng dấu hai chấm, theo sau là phạm vi truy cập và tên lớp cơ sở:

class Animal {
public:
    std::string name;
    
    void eat() {
        std::cout << name << " is eating" << std::endl;
    }
};

class Dog : public Animal {
public:
    void bark() {
        std::cout << name << " says woof!" << std::endl;
    }
};

Lớp Dog giờ có thể truy cập cả name và eat() từ Animal, đồng thời có phương thức bark() riêng. Đây chính là bản chất của kế thừa (inheritance): tái sử dụng code có sẵn trong khi bổ sung chức năng mới.

Dog myDog;
myDog.name = "Buddy";
myDog.eat();    // Kế thừa từ Animal
myDog.bark();   // Định nghĩa trong Dog

Từ khóa public đứng trước Animal xác định kiểu kế thừa. Kế thừa công khai có nghĩa là các thành viên công khai của lớp cơ sở vẫn công khai trong lớp dẫn xuất. Đây là hình thức phổ biến nhất và mô hình hóa mối quan hệ “là một”: Dog là một Animal.

challenge icon

Thử thách

Dễ

Hãy xây dựng một hệ thống phân cấp phương tiện đơn giản để minh họa cách tính kế thừa hoạt động. Bạn sẽ tạo lớp cơ sở Vehicle và lớp dẫn xuất Motorcycle mở rộng lớp đó với hành vi chuyên biệt.

Bạn sẽ sắp xếp code trong ba tệp:

  • Vehicle.h: Định nghĩa lớp cơ sở Vehicle với:
    • Một thành viên công khai std::string brand
    • Một thành viên công khai int year
    • Một phương thức công khai displayInfo() in ra hãng và năm sản xuất của phương tiện theo định dạng: Brand: <brand>, Year: <year>
  • Motorcycle.h: Định nghĩa lớp Motorcycle kế thừa công khai từ Vehicle. Lớp dẫn xuất này cần bổ sung:
    • Một thành viên công khai int engineCC biểu thị dung tích động cơ
    • Một phương thức công khai revEngine() in ra: <brand> goes vroom vroom!

    Lớp Motorcycle sẽ tự động kế thừa brand, year và displayInfo() từ Vehicle.

  • main.cpp: Đọc ba đầu vào, mỗi đầu vào trên một dòng riêng:
    1. Tên hãng (chuỗi)
    2. Năm sản xuất (số nguyên)
    3. Dung tích động cơ tính bằng CC (số nguyên)

    Tạo một đối tượng Motorcycle, gán giá trị cho các thành viên được kế thừa (brand và year) cũng như thành viên riêng engineCC. Sau đó tạo ba dòng đầu ra theo thứ tự: trước tiên gọi phương thức được kế thừa displayInfo(), tiếp theo tự in dung tích động cơ bằng std::cout << "Engine: " << moto.engineCC << "cc" << std::endl;, cuối cùng gọi phương thức riêng của xe máy revEngine(). Cách này minh họa tính kế thừa bằng việc sử dụng cả phương thức được kế thừa lẫn phương thức riêng của lớp dẫn xuất.

    Định dạng đầu ra:

    Brand: <brand>, Year: <year>
    Engine: <engineCC>cc
    <brand> goes vroom vroom!

Ví dụ, với các đầu vào Harley, 2022 và 1200:

Brand: Harley, Year: 2022
Engine: 1200cc
Harley goes vroom vroom!

Đừng quên thêm header guard vào các tệp header và dùng #include "Vehicle.h" trong header của Motorcycle để truy cập lớp cơ sở.

Tự làm thử

#include <iostream>
#include <string>
#include "Motorcycle.h"

using namespace std;

int main() {
    string brand;
    int year;
    int engineCC;

    cin >> brand;
    cin >> year;
    cin >> engineCC;

    // TODO: Tạo một đối tượng Motorcycle
    // TODO: Gán giá trị cho các thành viên brand, year và engineCC
    // TODO: Gọi displayInfo() để hiển thị thông tin kế thừa
    // TODO: In ra thông tin động cơ theo định dạng: Engine: <engineCC>cc
    // TODO: Gọi revEngine() để minh họa hành vi riêng của xe máy

    return 0;
}
quiz iconTự kiểm tra

Bài học này có một bài trắc nghiệm ngắn. Bắt đầu bài học để trả lời và theo dõi tiến độ.

Tất cả bài học trong Lập trình hướng đối tượng

Tự luyện tập: Trình biên dịch C++ online