Menu
CoddyTech

Trừu tượng hóa trong lập trình là gì?

Trong lập trình, trừu tượng hóa là giấu đi chi tiết cách một thứ hoạt động đằng sau một interface đơn giản hơn, để bạn dùng được nó mà chỉ cần biết nó làm gì. Gọi sorted(names) là sắp xếp được list mà không cần viết, thậm chí không cần nhìn thấy, thuật toán sắp xếp.

Tác giả Kevin Spektor, Co-founder & CTO

Cập nhật 24 tháng 9, 2026

Khi viết print("hi"), bạn không nghĩ đến chuyện các chữ cái đó đến được màn hình bằng cách nào. Bên dưới một dòng ấy, Python biến văn bản thành byte rồi nhờ hệ điều hành ghi chúng ra, hệ điều hành chuyển chúng cho terminal, và terminal vẽ từng chữ thành điểm ảnh bằng một phông chữ. Mỗi tầng hứa với tầng phía trên một điều đơn giản và giấu đi cách nó giữ lời hứa đó. Sự che giấu ấy chính là trừu tượng hóa (abstraction), và mọi chương trình đều nằm trên rất nhiều tầng như vậy.

Các tầng trừu tượng

TầngBạn làm việc vớiThứ được giấu đi
Chương trình của bạnprint("hi"), sorted(names)Cách thư viện làm việc
Python và thư viện chuẩnChuỗi, list, tệpQuản lý bộ nhớ, system call
Trình thông dịch (CPython)BytecodeCode C và mã máy chạy nó
Hệ điều hànhTệp, tiến trìnhKhối đĩa, driver thiết bị, lập lịch CPU
Phần cứngLệnh máyTransistor và tín hiệu điện

Mỗi tầng được xây từ tầng bên dưới và có thể hiểu được mà không cần biết tầng đó. Bạn viết được Python chạy tốt mà không cần biết khối đĩa là gì, và hệ điều hành lưu được tệp mà không cần biết tệp đó chứa code Python.

Trừu tượng hóa hoạt động thế nào trong code

Lập trình viên tự xây tầng của mình theo hai cách chính.

Trừu tượng hóa thủ tục là một hàm. Tên, tham số và giá trị trả về là interface; thân hàm là chi tiết được giấu đi. Khi đã có average(scores), phần còn lại của chương trình cứ thế dùng mà không cần đọc xem nó cộng và chia ra sao.

Trừu tượng hóa dữ liệu định nghĩa một kiểu bằng những gì bạn làm được với nó, chứ không bằng cách nó lưu trữ. Hàng đợi là "thêm vào cuối, lấy ra từ đầu". Các phần tử nằm trong bộ nhớ thế nào là chuyện riêng của nó:

serving soup
serving pasta
serving cake

Đoạn code ở dưới cùng không biết gì về deque. Nếu thay nó bằng một list thường và pop(0), đầu ra vẫn y hệt, chỉ chậm hơn với hàng đợi dài, vì xóa phần tử đầu tiên của list sẽ phải dịch mọi phần tử còn lại. Interface giữ nguyên, nên không có gì bên ngoài lớp phải thay đổi.

Lớp trừu tượng và interface

Trong lập trình hướng đối tượng, trừu tượng hóa thường có nghĩa là nêu rõ một họ lớp phải làm gì, còn làm thế nào thì để từng lớp tự quyết. Trong Python, module abc đánh dấu một phương thức là trừu tượng; lớp nào còn phương thức trừu tượng chưa cài đặt thì không thể tạo instance:

email to ana@example.com: Your package arrives today
sms to +15550100: Your package arrives today
Notifier is abstract: create an Email or an SMS instead

remind() chỉ phụ thuộc vào phần trừu tượng: bất cứ thứ gì có phương thức send. Thêm thông báo đẩy chỉ cần viết một lớp mới, còn remind() giữ nguyên. Bước cuối đó, một lời gọi chạy code khác nhau cho các lớp khác nhau, là đa hình: trừu tượng hóa định nghĩa interface chung, đa hình làm cho nó chạy được.

Java có những công cụ tương tự dưới dạng từ khóa:

interface Notifier {
    void send(String to, String text);
}

class Email implements Notifier {
    public void send(String to, String text) { /* talk to the mail server */ }
}

Viết new Notifier() là lỗi biên dịch, vì interface không có phần cài đặt nào để chạy. Tài liệu giải thích chi tiết về lớp trừu tượng và interface trong Java.

Trừu tượng hóa và đóng gói

Hai ý tưởng này đi cùng nhau thường xuyên đến mức rất dễ nhầm lẫn.

Trừu tượng hóaĐóng gói
Câu hỏi nó trả lờiThứ này làm gì?Ai được phép động vào dữ liệu?
Trọng tâmInterface: các thao tác được cung cấpBên trong: dữ liệu đằng sau interface
Công cụ chínhHàm, lớp trừu tượng, interface, moduleprivate, _name, property, #fields
Ví dụNotifier.send() dùng được cho cả email lẫn SMS_balance chỉ thay đổi qua withdraw()
Cấp độThiết kếCài đặt

Trừu tượng hóa quyết định thao tác nào được hiển thị; đóng gói đảm bảo phần còn lại được giấu kín. Lớp Queue ở trên làm cả hai: add và next là phần trừu tượng, còn dấu gạch dưới ở _items là phần đóng gói.

Trừu tượng bị rò rỉ và những lỗi khác

Năm 2002, Joel Spolsky đặt tên cho định luật trừu tượng rò rỉ: mọi sự trừu tượng không tầm thường đều để lọt ra một phần chi tiết bị giấu. Số thực dấu phẩy động là ví dụ kinh điển. Chúng trông như số thập phân bình thường, cho đến khi cách lưu trữ nhị phân bên dưới lộ ra:

0.30000000000000004
False

Cả 0.1 lẫn 0.2 đều không lưu chính xác được bằng các bit nhị phân, nên tổng bị lệch một chút. Bạn có thể dùng số thực nhiều năm mà không phải nghĩ đến chuyện này, nhưng không phải mãi mãi, vì thế biết thêm một tầng bên dưới tầng mình đang làm việc luôn có ích.

Thêm hai lỗi hay gặp:

  • Trừu tượng hóa quá sớm. Một hệ thống phân cấp lớp dựng cho những trường hợp không bao giờ đến chỉ là thêm code phải đọc và sửa. Sandi Metz tóm lại rằng trùng lặp code còn rẻ hơn nhiều so với một sự trừu tượng sai.
  • Nhầm trừu tượng hóa với từ khóa abstract. Lớp trừu tượng chỉ là một công cụ. Mọi hàm được đặt tên tốt cũng là một sự trừu tượng hóa.

Học tiếp ở đâu

Đọc đóng gói và đa hình để có bức tranh đầy đủ về hướng đối tượng. Trang hệ điều hành cho thấy sự trừu tượng lớn nhất mà chương trình của bạn dựa vào. Để luyện tập, khóa học Python cho bạn xây lớp và hàm ngay từ đầu, còn khóa học Java đi qua lớp trừu tượng và interface.

Câu hỏi thường gặp

Ví dụ về trừu tượng hóa là gì?
Hàm là ví dụ đơn giản nhất: bạn gọi len(items) vì biết nó trả về gì, chứ không cần biết Python đếm thế nào. Bàn đạp ô tô là phiên bản đời thường, vì bạn điều khiển tốc độ mà không cần biết động cơ đốt nhiên liệu ra sao. Trong code hướng đối tượng, một interface như Notifier với một phương thức send là lớp trừu tượng bao trùm email, SMS và thông báo đẩy.
Trừu tượng hóa trong Python là gì?
Mọi hàm, lớp và module trong Python đều là một sự trừu tượng hóa cho đoạn code bên trong nó. Muốn khai báo chính thức, module chuẩn abc cho phép bạn tạo lớp cơ sở trừu tượng bằng @abstractmethod; khi đó Python từ chối tạo đối tượng của lớp này, hay của bất kỳ lớp con nào chưa cài đặt đủ mọi phương thức trừu tượng.
Tính trừu tượng trong Java là gì?
Java thể hiện tính trừu tượng bằng lớp trừu tượng và interface. Lớp trừu tượng có thể chứa phương thức trừu tượng, tức phương thức không có thân và lớp con buộc phải cài đặt, và không thể khởi tạo bằng new. Interface liệt kê các phương thức mà lớp cài đặt nó phải cung cấp, và một lớp có thể cài đặt nhiều interface.
Bốn tính chất của OOP là gì?

Đóng gói, trừu tượng, kế thừa và đa hình. Đóng gói bảo vệ dữ liệu của đối tượng, trừu tượng chỉ để lộ những gì đối tượng làm, kế thừa cho một lớp dùng lại code của lớp khác, còn đa hình cho một đoạn code làm việc với nhiều kiểu thông qua một interface chung.

Trừu tượng hóa có thể làm code tệ đi không?

Có, khi nó đến quá sớm hoặc giấu nhầm thứ. Code được dựng cho những trường hợp không bao giờ xảy ra sẽ có thêm nhiều tầng phải đọc và sửa mà chẳng được lợi gì. Một nguyên tắc phổ biến là chờ đến khi bạn đã viết code tương tự hai hoặc ba lần, để hình dạng chung lộ rõ rồi mới đặt tên cho nó.

Hình minh họa các ngôn ngữ lập trình của Coddy

Học lập trình cùng Coddy

Bắt đầu