Cách Mô Phỏng Lập Trình Hướng Đối Tượng (OOP) Trong Ngôn Ngữ C: Đóng Gói, Kế Thừa Và Đa Hình

1. Giới thiệu

Ngôn ngữ lập trình C được rất nhiều lập trình viên yêu thích nhờ bối cảnh lịch sử lâu đời và khả năng kiểm soát cấp thấp. Tuy nhiên, C không phải là một “ngôn ngữ hướng đối tượng”. Nói cách khác, bản thân ngôn ngữ không hỗ trợ các tính năng hướng đối tượng như class, kế thừa hay đóng gói như Java hay C++. Tuy vậy, bạn vẫn có thể mô phỏng các khái niệm lập trình hướng đối tượng trong C và thực hiện được một số chức năng nhất định. Bài viết này sẽ lần lượt giải thích các khái niệm cơ bản như đóng gói, kế thừa và đa hình, cũng như cách triển khai lập trình hướng đối tượng bằng C.

2. Các khái niệm cơ bản về hướng đối tượng

Lập trình hướng đối tượng (OOP) nhằm mục đích quản lý dữ liệu và các phương thức thao tác với dữ liệu như một thể thống nhất. Nhờ đó, cấu trúc chương trình trở nên rõ ràng hơn, dễ tái sử dụng và bảo trì hơn. Các khái niệm chính của OOP gồm có đóng gói, kế thừađa hình. Mặc dù C không hỗ trợ trực tiếp các khái niệm này, nhưng với một chút sáng tạo, bạn vẫn có thể tái hiện chúng một cách giả lập.

2.1 Đóng gói

Đóng gói là việc gom nhóm dữ liệu và các thao tác (phương thức) vào một đơn vị duy nhất, đồng thời kiểm soát quyền truy cập từ bên ngoài. Trong C, bạn có thể sử dụng struct để gom nhóm dữ liệu. Struct đóng vai trò giống như class khi cho phép kết hợp nhiều dữ liệu lại với nhau.

typedef struct {
    int age;
    char name[50];
} Person;

Với struct này, kiểu dữ liệu Person đóng gói thông tin tuổi và tên. Nhờ đó, bạn có thể khởi tạo các instance của Person và thao tác với chúng.

2.2 Kế thừa

Trong C không tồn tại khái niệm kế thừa, nên bạn không thể tạo mối quan hệ cha-con như class. Tuy nhiên, bằng cách sử dụng struct lồng nhau, bạn có thể mô phỏng một cơ chế gần giống kế thừa.

typedef struct {
    int age;
} Parent;

typedef struct {
    Parent parent;
    int studentID;
} Child;

Đoạn mã trên thể hiện struct Child chứa struct Parent như một thành viên, qua đó mô phỏng quan hệ kế thừa.

2.3 Đa hình (Polymorphism)

Đa hình là khả năng một thao tác có thể thực hiện khác nhau tùy vào kiểu đối tượng. Trong C, bạn có thể sử dụng con trỏ hàm để đạt được đa hình. Con trỏ hàm là biến chứa địa chỉ hàm, cho phép gọi động các hàm khác nhau.

typedef int (*OperationFunc)(int, int);

int add(int a, int b) {
    return a + b;
}

int multiply(int a, int b) {
    return a * b;
}

OperationFunc op = add;  // Thiết lập con trỏ đến hàm add
printf("%d", op(3, 4));  // Kết quả: 7
op = multiply;           // Đổi sang hàm multiply
printf("%d", op(3, 4));  // Kết quả: 12

Bằng cách này, bạn có thể thực hiện các xử lý khác nhau với cùng một con trỏ hàm.

3. Cách triển khai class trong C

Để lập trình hướng đối tượng bằng C, bạn cần tạo ra khái niệm class một cách giả lập. Kết hợp struct và con trỏ hàm, bạn có thể xây dựng một cấu trúc gần giống class.

3.1 Sử dụng struct như class

Để mô phỏng class trong C, hãy dùng struct để gom nhóm dữ liệu và các phương thức. Các phương thức sẽ được định nghĩa dưới dạng hàm và quản lý qua con trỏ hàm bên trong struct.

typedef struct {
    int age;
    void (*setAge)(struct Person*, int);
    int (*getAge)(struct Person*);
} Person;

void setAge(struct Person* p, int age) {
    p->age = age;
}

int getAge(struct Person* p) {
    return p->age;
}

Person person = {0, setAge, getAge};
person.setAge(&person, 25);
printf("Age: %d", person.getAge(&person));  // Kết quả: 25

Ở ví dụ trên, struct Person sở hữu hai phương thức setAgegetAge, hoạt động gần giống class.

4. Triển khai phương thức (method)

Để tái hiện tính năng “phương thức” trong OOP bằng C, hãy sử dụng con trỏ hàm. Điều này giúp bạn định nghĩa phương thức như một biến thành viên trong struct.

typedef struct {
    int age;
    void (*setAge)(struct Person*, int);
} Person;

void setAge(struct Person* p, int age) {
    p->age = age;
}

5. Tổng kết và ứng dụng

Dù C không hỗ trợ trực tiếp OOP, bạn hoàn toàn có thể hiện thực nó nếu biết cách vận dụng struct, con trỏ hàm và quản lý bộ nhớ hợp lý. Qua đó, bạn có thể mô phỏng được các khái niệm như class hay kế thừa trong C.