Bài 13. Kế thừa, dataclass và kiểu gợi ý

Tiếp nối OOP: kế thừa và đa hình, lớp trừu tượng, dataclass giúp viết lớp dữ liệu ngắn gọn, và type hints giúp mã rõ ràng, được kiểm tra bởi công cụ.

55 phútTrung cấp
Bạn sẽ học được
  • Kế thừa, ghi đè, dùng super()
  • Tạo lớp trừu tượng với abc
  • Dùng @dataclass, Enum
  • Viết type hints và kiểm tra bằng mypy/Pyright
Thuật ngữ cần biết
Kế thừa
Lớp con nhận thuộc tính, phương thức của lớp cha.
Đa hình
Cùng lời gọi, mỗi lớp xử lý theo cách riêng.
dataclass
Decorator tự sinh __init__, __repr__, __eq__.
Type hint
Chú thích kiểu, không ảnh hưởng khi chạy.

Khái niệm và lý thuyết

Kế thừa thể hiện quan hệ “là một” (Sinh viên là một Người). Nếu quan hệ là “có một” (Lớp học có nhiều Sinh viên) thì dùng kết hợp (composition). Lớp trừu tượng định nghĩa hợp đồng mà lớp con bắt buộc cài đặt.

Type hints (PEP 484) là chú thích; Python không kiểm tra khi chạy, nhưng trình soạn thảo và công cụ như mypy, Pyright dùng để phát hiện lỗi sớm và gợi ý mã. Từ Python 3.14, chú thích kiểu được đánh giá trễ (lazy), không còn lỗi khi tham chiếu lớp chưa khai báo.

Kế thừa và lớp trừu tượng

from abc import ABC, abstractmethod
import math

class Hinh(ABC):
    @abstractmethod
    def dien_tich(self) -> float: ...
    def mo_ta(self) -> str:
        return f"{type(self).__name__}: {self.dien_tich():.2f}"

class Tron(Hinh):
    def __init__(self, r: float): self.r = r
    def dien_tich(self) -> float: return math.pi * self.r ** 2

class Vuong(Hinh):
    def __init__(self, a: float): self.a = a
    def dien_tich(self) -> float: return self.a ** 2

for h in [Tron(1), Vuong(2)]:
    print(h.mo_ta())            # đa hình
# Hinh() -> TypeError: không tạo được lớp trừu tượng

dataclass và Enum

from dataclasses import dataclass, field
from enum import Enum

class TrangThai(Enum):
    MOI = "mới"
    DANG_LAM = "đang làm"
    XONG = "xong"

@dataclass(order=True)
class CongViec:
    uu_tien: int
    tieu_de: str = field(compare=False)
    trang_thai: TrangThai = TrangThai.MOI
    nhan: list[str] = field(default_factory=list)

ds = [CongViec(2, "Viết báo cáo"), CongViec(1, "Học Python", nhan=["học"])]
print(sorted(ds)[0])
# CongViec(uu_tien=1, tieu_de='Học Python', trang_thai=<TrangThai.MOI: 'mới'>, nhan=['học'])

Thêm frozen=True để đối tượng bất biến; slots=True để tiết kiệm bộ nhớ.

Type hints thường dùng

from typing import Literal, TypedDict

def tim(ds: list[str], tu: str) -> int | None: ...
type DiemSo = dict[str, float]                  # type alias (3.12+)
CheDo = Literal["sang", "toi"]

class NguoiDung(TypedDict):
    id: int
    ten: str

def dau_tien[T](ds: list[T]) -> T:              # generic (3.12+)
    return ds[0]
pip install mypy
mypy chuong_trinh.py
Mẹo hay

Trong VS Code, bật Pylance với “Type Checking Mode: basic” để thấy lỗi kiểu ngay khi gõ mà không cần chạy lệnh.

Lưu ý

Kế thừa nhiều tầng làm mã khó theo dõi. Nếu lớp con chỉ dùng lại vài hàm của lớp cha, cân nhắc composition.

Thực hành
  1. Tạo lớp cha NhanVien (trừu tượng, tinh_luong) và hai lớp con.
  2. Chuyển lớp SinhVien ở Bài 12 sang dataclass.
  3. Dùng Enum cho các mức xếp loại học lực.
  4. Thêm type hints cho dự án Bài 10 và chạy mypy, sửa hết lỗi.
Tóm tắt bài học
  • Kế thừa cho quan hệ “là một”, composition cho “có một”.
  • ABC + @abstractmethod tạo hợp đồng.
  • dataclass, Enum giúp lớp dữ liệu ngắn gọn.
  • Type hints + mypy/Pyright bắt lỗi trước khi chạy.