tinbc tinbc

Bài 12: Lập trình hướng đối tượng cơ bản (class) trong Python

Thợ Code5 phút đọc
Bài 12: Lập trình hướng đối tượng cơ bản (class) trong Python

Bài 11 bạn đã dùng module để tổ chức code. Bài này bước sang một cách tư duy mới: lập trình hướng đối tượng (OOP) — gói dữ liệuhành vi liên quan vào cùng một chỗ gọi là class. Nghe học thuật nhưng ý tưởng rất đời thường: mô tả một “sự vật” (tài khoản, sản phẩm, chiếc xe) bằng những gì nó và những gì nó làm được. Đây là nền tảng của hầu hết phần mềm lớn.

⏱️ Cách học bài này (~30 phút): đọc khái niệm class/đối tượng (12’), tự gõ và chạy ví dụ + bài tập (13’), tự kiểm + lưu code mang về (5’).

Mục tiêu bài học

Sau bài này bạn sẽ:

  • Hiểu class (khuôn mẫu) và đối tượng (bản thể cụ thể).
  • Viết __init__ để gán thuộc tính ban đầu.
  • Thêm phương thức (hành vi) cho class.
  • Tạo và dùng nhiều đối tượng từ một class.

Nội dung: class và đối tượng

1. Class là “khuôn”, đối tượng là “bản thể”

Hình dung: class TaiKhoankhuôn mẫu mô tả một tài khoản gồm tên chủsố dư. Từ khuôn đó, mỗi người dùng thật là một đối tượng riêng.

class TaiKhoan:
    def __init__(self, ten, so_du):
        self.ten = ten        # thuộc tính: dữ liệu của đối tượng
        self.so_du = so_du

tk1 = TaiKhoan("Lan", 100)    # tạo một đối tượng
print(tk1.ten, tk1.so_du)     # Lan 100
  • __init__ tự chạy khi tạo đối tượng, gán dữ liệu ban đầu.
  • selfchính đối tượng đang thao tác — nhờ nó mỗi đối tượng giữ dữ liệu riêng.

2. Thêm phương thức (hành vi)

Phương thức là hàm nằm trong class, mô tả việc đối tượng làm được:

class TaiKhoan:
    def __init__(self, ten, so_du):
        self.ten = ten
        self.so_du = so_du

    def nap(self, tien):
        self.so_du += tien          # đổi dữ liệu của chính đối tượng

    def xem(self):
        print(f"{self.ten}: {self.so_du}đ")

tk1 = TaiKhoan("Lan", 100)
tk1.nap(50)     # gọi phương thức
tk1.xem()       # Lan: 150đ

Mọi phương thức đều nhận self làm tham số đầu tiên để biết đang làm việc với đối tượng nào.

3. Một class, nhiều đối tượng

tk1 = TaiKhoan("Lan", 100)
tk2 = TaiKhoan("Nam", 0)
tk1.nap(50)
tk2.nap(200)
tk1.xem()   # Lan: 150đ
tk2.xem()   # Nam: 200đ

Hai đối tượng dùng chung hành vi (nap, xem) nhưng dữ liệu riêng — đó là sức mạnh của class.

Code mẫu có chú thích: quản lý sản phẩm

class SanPham:
    def __init__(self, ten, gia, so_luong):
        self.ten = ten
        self.gia = gia
        self.so_luong = so_luong

    def tong_tien(self):                 # phương thức tính toán
        return self.gia * self.so_luong

    def mo_ta(self):
        print(f"{self.ten}: {self.so_luong} cái, tổng {self.tong_tien()}đ")

sp = SanPham("Bút bi", 5000, 10)
sp.mo_ta()                # Bút bi: 10 cái, tổng 50000đ

Mấu chốt: gói dữ liệu (ten, gia, so_luong) và hành vi (tong_tien, mo_ta) vào một chỗ — gọn và rõ.

Bài thực hành code (tự gõ)

Bài 1 — Class đơn giản: tạo class HocSinh với thuộc tính tendiem; in ra bằng câu lệnh print.

Bài 2 — Thêm phương thức: thêm phương thức xep_loai() trả về “Giỏi” nếu diem >= 8, ngược lại “Khá”.

Bài 3 — Nhiều đối tượng: tạo 2 học sinh, gọi xep_loai() cho từng người và in kết quả.

Lỗi thường gặp & cách sửa

  • Quên self trong định nghĩa phương thức (def nap(tien):) → lỗi khi gọi. Luôn để self là tham số đầu tiên.
  • Quên self. khi truy cập thuộc tính (so_du += tien thay vì self.so_du += tien) → Python báo biến chưa định nghĩa.
  • Nhầm class với đối tượngTaiKhoan.xem() (gọi trên class) sai; phải tạo đối tượng tk1 = TaiKhoan(...) rồi tk1.xem().
  • Quên __init__ có hai dấu gạch dưới mỗi bên (__init__, không phải _init_).

💾 Mang về — mẫu class cơ bản

# class_mau.py
class NhanVat:
    def __init__(self, ten, mau):
        self.ten = ten
        self.mau = mau          # máu (HP)

    def bi_danh(self, sat_thuong):
        self.mau -= sat_thuong
        if self.mau < 0:
            self.mau = 0

    def con_song(self):
        return self.mau > 0

hero = NhanVat("Anh Hùng", 100)
hero.bi_danh(30)
print(hero.mau, "-", "còn sống" if hero.con_song() else "đã ngã")  # 70 - còn sống

Thuật ngữ chốt

Thuật ngữ Giải thích ngắn
class Khuôn mẫu mô tả một loại sự vật
đối tượng (object) Bản thể cụ thể tạo từ class
thuộc tính (attribute) Dữ liệu của đối tượng (self.ten)
phương thức (method) Hàm nằm trong class (hành vi)
__init__ Phương thức khởi tạo, chạy khi tạo đối tượng
self Chính đối tượng đang thao tác

Tự kiểm tra & lời giải

  1. __init__ chạy khi nào? (Đáp án: tự chạy khi tạo một đối tượng mới)
  2. self đại diện cho gì? (Đáp án: chính đối tượng đang được thao tác)
  3. Từ một class tạo được mấy đối tượng? (Đáp án: bao nhiêu tuỳ ý, mỗi cái dữ liệu riêng)

Lời giải Bài thực hành:

class HocSinh:
    def __init__(self, ten, diem):
        self.ten = ten
        self.diem = diem

    def xep_loai(self):
        return "Giỏi" if self.diem >= 8 else "Khá"

hs1 = HocSinh("Lan", 9)
hs2 = HocSinh("Nam", 6)
print(hs1.ten, hs1.xep_loai())   # Lan Giỏi
print(hs2.ten, hs2.xep_loai())   # Nam Khá

Ghi nhớ nhanh

  • class = khuôn, đối tượng = bản thể; một class tạo nhiều đối tượng.
  • __init__(self, ...) gán thuộc tính ban đầu; self giữ dữ liệu riêng.
  • Phương thức = hàm trong class, luôn có self đầu tiên; gọi bằng doi_tuong.phuong_thuc().

👉 Bài tập về nhà: tạo class TaiKhoan có thêm phương thức rut(tien) — chỉ cho rút khi đủ số dư, thiếu thì báo “Không đủ số dư” (gợi ý: if tien > self.so_du: thì báo lỗi, ngược lại self.so_du -= tien). Bài tiếp theo trong series: Bài 13 — Cài và dùng thư viện ngoài (pip) (sắp đăng).

Chia sẻ:
0.0 0 lượt đánh giá

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

Class và đối tượng (object) trong Python là gì?

Class là ‘khuôn mẫu’ mô tả một loại sự vật gồm dữ liệu (thuộc tính) và hành vi (phương thức); còn đối tượng là một ‘bản thể’ cụ thể tạo ra từ khuôn đó. Ví dụ class ‘ChiecXe’ là khuôn, còn chiếc xe cụ thể của bạn là một đối tượng. Từ một class bạn tạo được nhiều đối tượng, mỗi cái có dữ liệu riêng nhưng dùng chung các hành vi.

Hàm __init__ và self trong class dùng để làm gì?

init là phương thức khởi tạo, tự chạy khi bạn tạo một đối tượng mới, dùng để gán dữ liệu ban đầu. ‘self’ đại diện cho chính đối tượng đang được thao tác, giúp mỗi đối tượng giữ dữ liệu riêng của nó. Mọi phương thức trong class đều nhận self làm tham số đầu tiên để biết nó đang làm việc với đối tượng nào.

Khi nào nên dùng class thay vì hàm thường?

Dùng class khi bạn có những ‘sự vật’ gắn liền dữ liệu với hành vi, và cần tạo nhiều bản giống nhau — ví dụ tài khoản người dùng, sản phẩm, nhân vật game. Với các tác vụ đơn giản, rời rạc thì hàm thường là đủ và gọn hơn. Class giúp code lớn có tổ chức, dễ tái dùng và mở rộng, nhưng không phải lúc nào cũng cần.

Thợ Code

Thợ Code

Thợ code chính hiệu, thích dắt người mới qua mấy đoạn 'khó nhằn' bằng giọng nhẹ tênh. Châm ngôn: cứ làm dự án thật, sai thì sửa, vui là chính.

Bài liên quan

10 lỗi người mới học lập trình hay mắc và cách tránh
Lập trình

10 lỗi người mới học lập trình hay mắc và cách tránh

Học lập trình mãi không tiến, dễ nản và bỏ cuộc? Phần lớn do 10 sai lầm rất phổ biến của người mới. Bài này chỉ từng lỗi và cách sửa cụ thể — để bạn học nhanh hơn và không bỏ giữa chừng.

Bài 10: Dự án — hoàn thiện trang cá nhân (HTML + CSS + JS)
Lập trình

Bài 10: Dự án — hoàn thiện trang cá nhân (HTML + CSS + JS)

Bài 10 series Web cơ bản (bài học 30 phút): dự án tổng hợp — ghép HTML, CSS responsive và JavaScript thành một trang cá nhân hoàn chỉnh có nút đổi giao diện sáng/tối; kèm code đầy đủ và gợi ý mở rộng.