Trang tài liệu
Khóa học C++ nền tảng
Chương 8. Cấu trúc và lớp
Lập trình Object-Oriented (OOP) trong C++

Lập trình Object-Oriented (OOP) trong C++

Lập trình Object-Oriented (OOP) là một mô hình lập trình sử dụng các đối tượng, là các thể hiện của các lớp, để thực hiện các thao tác và tương tác với nhau. Trong C++, bạn có thể đạt được OOP thông qua việc sử dụng các lớp và đối tượng.

Các lớp

Một lớp là một kế hoạch chi tiết để tạo các đối tượng. Nó xác định cấu trúc (thành viên dữ liệu) và hành vi (hàm thành viên) cho một loại đối tượng. Đây là một ví dụ về một lớp đơn giản:

class Dog {
public:
    std::string name;
    int age;

    void bark() {
        std::cout << name << " barks!" << std::endl;
    }
};

Lớp Dog này có hai thành viên dữ liệu: name và age, và một thành viên hàm bark. Bạn có thể tạo một đối tượng của lớp này và truy cập các thành viên của nó như sau:

Dog myDog;
myDog.name = "Fido";
myDog.age = 3;
myDog.bark(); // đầu ra: Fido barks!

Đóng gói

Đóng gói là khái niệm gói dữ liệu và các hàm hoạt động trên dữ liệu đó trong một đơn vị, chẳng hạn như một lớp. Nó giúp ẩn các chi tiết triển khai bên trong của một lớp và chỉ hiển thị các thông tin và hàm cần thiết. Trong C++, bạn có thể sử dụng các chỉ định truy cập như public, private, và protected để kiểm soát khả năng hiển thị và khả năng truy cập của các thành viên lớp. Ví dụ:

class Dog {
private:
    std::string name;
    int age;

public:
    void setName(std::string n) {
        name = n;
    }

    void setAge(int a) {
        age = a;
    }

    void bark() {
        std::cout << name << " barks!" << std::endl;
    }
};

Trong ví dụ này, chúng tôi đã đặt các thành viên dữ liệu name và age ở private và thêm các hàm thành viên công cộng setName và setAge để sửa đổi chúng. Bằng cách này, dữ liệu nội bộ của lớp Dog được bảo vệ và chỉ có thể truy cập thông qua các hàm được cung cấp.

Kế thừa

Kế thừa là khái niệm dẫn xuất các lớp mới từ các lớp hiện có, cho phép tổ chức và tái sử dụng mã code. Trong C++, tính kế thừa đạt được bằng cách sử dụng dấu hai chấm : theo sau là từ chỉ định truy cập của lớp cơ sở và tên lớp cơ sở. Ví dụ:

class Animal {
public:
    void breathe() {
        std::cout << "I can breathe" << std::endl;
    }
};

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

Trong ví dụ này, lớp Dog kế thừa từ lớp Animal, vì vậy lớp Dog có thể truy cập hàm Breath từ lớp Animal. Khi bạn tạo một đối tượng Dog, bạn có thể sử dụng cả hai hàm breath và dark.

Dog myDog;
myDog.breathe(); // đầu ra: I can breathe
myDog.bark(); // đầu ra: Dog barks!

Đa hình

Tính đa hình cho phép bạn sử dụng một giao diện duy nhất để biểu diễn các loại khác nhau. Trong C++, nó chủ yếu đạt được bằng cách sử dụng nạp chồng hàm, hàm ảo và ghi đè. Ví dụ:

class Animal {
public:
    virtual void makeSound() {
        std::cout << "The Animal makes a sound" << std::endl;
    }
};

class Dog : public Animal {
public:
    void makeSound() override {
        std::cout << "Dog barks!" << std::endl;
    }
};

class Cat : public Animal {
public:
    void makeSound() override {
        std::cout << "Cat meows!" << std::endl;
    }
};

Trong ví dụ này, chúng ta có một lớp cơ sở Animal với hàm makeSound ảo. Sau đó, chúng tôi lấy được hai lớp, Dog và Cat, ghi đè lên hàm makeSound. Điều này cho phép hành vi đa hình, trong đó một con trỏ Animal hoặc tham chiếu có thể được sử dụng để truy cập đúng hàm makeSound tùy thuộc vào loại lớp dẫn xuất.

Animal *animals[2] = {new Dog, new Cat};
animals[0]->makeSound(); // đầu ra: Dog barks!
animals[1]->makeSound(); // đầu ra: Cat meows!

Đó là tổng quan ngắn gọn về các khái niệm lập trình hướng đối tượng trong C++.