Phân Biệt Abstract Class Và Interface Trong C

Abstract class và Interface là hai khái niệm cơ bản trong lập trình hướng đối tượng, tuy nhiên trong C++ thì việc phân biệt abstract class và interface không đơn giản như những ngôn ngữ khác. Cùng tìm hiểu trong bài viết sau nhé.

Abstract class là gì?

Abstract class là một class không có thông tin về nội dung thực hiện và bắt buộc cái subclass (class con) phải định nghĩa các phương thức ở lớp abstract. Với lớp abstract, chúng ta có thể công khai mặt tiền của object nhưng vẫn giấu đi các tiến trình cài đặt ở phía sau. Ví dụ với lớp string, chúng ta chỉ cần gọi phương thức toUpperCase() để biến chuỗi thường thành chuỗi in hoa mà không cần quan tâm đến phương thức đó được cài đặt như nào. Abstract class giúp chúng ta đạt được tính đa hình lúc Runtime, tức là cùng một class có thể cho ra nhiều biến thể mà biến thể đó không phải được định nghĩa ở lớp abstract mà được định nghĩa ở lớp con của nó. Việc call hàm đối tượng của lớp dẫn xuất thông qua con trỏ của lớp cơ sở (lớp abstract) sẽ được quyết định lúc Runtime. Các bạn cần hiểu được đa hình trong Compile và đa hình trong Runtime ở bài viết này nhé.

Ví dụ về việc cài đặt và sử dụng một lớp abstract trong C++.

Kết quả sau khi chạy chương trình.

Giải thích:

Trong C++ chúng ta không có từ khóa abstract để compiler hiểu rằng đây là một lớp abstract mà chúng ta phải khai báo một hàm ảo trong lớp đó để lớp con (lớp kế thừa) ghi đè(overriding) lại phương thức đó. Ở code phía trên class Computer là một lớp abstract được khai báo với hàm ảo(virtual function) là hàm Model. Ở lớp con Lenovo ghi đè lại phương thức Model ở lớp Computer. Trong hàm main chúng ta khai báo con trỏ của lớp Computer trỏ vào vùng nhớ của lớp con và gọi hàm Model thì lúc này hàm Model được ghi đè ở lớp con được gọi. Tương tự con trỏ của lớp abstract trỏ vào vùng nhớ của lớp Dell và gọi hàm Model ra thì hàm Model của lớp Dell sẽ được ghi đè. Nếu không khai báo hàm Model ở lớp Computer là hàm ảo thì trình biên dịch sẽ gọi hàm Model tại lớp cơ sở. Thử xem có ra kết quả như bên dưới không nhé.

Interface là gì?

Trong C++ việc khai báo một interface có nghĩa là chúng ta khai báo với class với hàm thuần ảo và một phương thức hủy ảo (virtual destructor). Tới đây chúng ta tìm hiểu một chút về hàm thuần ảo trong C++ nhé. Hàm thuần ảo được khai báo với cú pháp như sau.

virtual () = 0;

Ví dụ:

Ở đây tôi khai báo lớp IShape (khai báo class với chữ “I” trước tên class để đánh dấu cho người đọc code biết rằng đây là một interface, đây là một chuẩn coding trong C++) có một phương thức thuần ảo là phương thức tinnhDienTich(). Lưu ý chỉ có hàm được đánh dấu với từ khóa virtual thì mới được gán bằng 0. Chúng ta có thể hiểu hàm tinnhDienTich()có thể dùng để tính diện tích cho hình chữ nhật, hình tròn, hình vuông,… Như vậy nếu chúng ta tạo một class Rectangle kế thừa class IShape và định nghĩa lại phương thức tinnhDienTich() để tính diện tích hình chữ nhật thì sẽ thu được đa hình trong Runtime tương tự như abstract class.

Có thể hiểu Interface là một bản mô tả hành vi hoặc khả năng của một class mà không đưa ra cách thực hiện cụ thể của class đó như thế nào.

Vậy khi nào dùng abstract class, khi nào dùng interface?

Tới đây chắc sẽ có nhiều bạn thắc mắc abstract class khác thế quái nào interface. Mới đầu khi tiếp cận với hai khái niệm này tôi cũng như các bạn không biết khi nào dùng abstract class khi nào dùng interface. Giả sử chúng ta có một lớp abstract Xe có thuộc tính động cơ và phương thức khởi động và tắt máy. Xe máy, xe ô tô, xe tải,… đều có chung phương thức và thuộc tính của lớp Xe. Vậy có thể hiểu abstract class như là một bản thiết kế chung cho tất cả các class, nó đại diện cho mối quan hệ “IS-A”(Ô tô là Xe).

Interface giống như một bản hợp đồng vậy, bất kì lớp nào triên khai một interface đó thì phải đồng ý với bản thiết kế mà interface đó đưa ra. Ví dụ xe bus có thể chở khách còn xe tải có hàng. Việc chở khách hay chở hàng là một phương thức không bắt buộc đối với lớp xe nên ta tạo interface ChoKhach và ChoHang để lớp XeBus và XeTai có thể implement nó. Vậy chúng ta cần interface khi chúng ta cần cung cấp các phương thức bổ sung cho một class mà những phương thức này không bắt buộc đối với class đó, nó đại diện cho mối quan hệ “LIKE-A”(Xe bus có thể chở khách).

Lời kết

Qua bài viết này tôi đã hướng dẫn các bạn cách cài đặt abstract class và interface trong C++ cũng như biết khi nào nên sử dụng chúng. Tuy cách cài đặt có khác so với các ngôn ngữ bậc cao sau này như Java hay C# nhưng về bản chất thì vẫn không thay đổi.

Leave a Reply

Your email address will not be published. Required fields are marked *