🌱 [Python] 17 - OOP Concepts: Class and Object

🌱 [Python] 17 - OOP Concepts: Class and Object

    Class và Object là hai khái niệm trung tâm trong lập trình hướng đối tượng (OOP). Bài viết này sẽ cùng mọi người tìm hiểu về hai khái niệm quan trọng này và cách sử dụng chúng trong ngôn ngữ lập trình Python.

1 - Giới thiệu về Class và Object

    Class và Object là hai khái niệm trung tâm trong lập trình hướng đối tượng (OOP). - Class là bản thiết kế (blueprint) mô tả cấu trúc và hành vi (attributes và methods) của đối tượng. Object là thể hiện cụ thể (instance) được tạo ra từ class.

Class

    Class định nghĩa cấu trúc và hành vi của các đối tượng bằng cách đóng gói dữ liệu (thuộc tính) và phương thức (hàm). Bản thân class không chiếm bộ nhớ cho đến khi một object được khởi tạo từ class đó.

    Bạn có thể định nghĩa class trong Python bằng từ khóa class. Mỗi class có thể bao gồm:

  • Thuộc tính (attributes): lưu trữ dữ liệu hoặc trạng thái của đối tượng.
  • Phương thức (methods): định nghĩa hành vi của đối tượng.

    Ví dụ: class Car có thể định nghĩa các thuộc tính như màu sắc và tốc độ, cũng như các phương thức như drive() hoặc stop().

class Car:
def __init__(self, color, speed):
self.color = color
self.speed = speed
def drive(self):
print(f"The {self.color} car is driving at {self.speed} km/h.")

Object

    Object - Đối tượng là một thể hiện cụ thể của một class. Nó đại diện cho một thực thể cụ thể với dữ liệu và hành vi riêng biệt, được định nghĩa bởi class. Khi một object được tạo, bộ nhớ được cấp phát để lưu trữ dữ liệu của nó.

    ↪ Khi bạn gọi class như một hàm, Python sẽ tự động tạo ra một object.

    Ví dụ: my_car = Car("red", 100) tạo ra một object với tên my_car với các thuộc tính cụ thể.

# Creating objects from the Car class
my_car = Car("red", 100)
your_car = Car("blue", 120)
# Accessing methods and attributes
my_car.drive() # Output: The red car is driving at 100 km/h
your_car.drive() # Output: The blue car is driving at 120 km/h

python OOP: Class and Object

2 - Phương thức khởi tạo (__init__)

    Hàm đặc biệt __init__() được gọi tự động khi một object được tạo. Nó giúp khởi tạo các giá trị mặc định cho object.

class Car:
def __init__(self, brand, model):
self.brand = brand
self.model = model

my_car = Car("Toyota", "Camry")
print(my_car.brand) # Toyota

3 - Từ khóa self và ý nghĩa

    Từ khóa self đại diện cho chính object hiện tại. Python sử dụng self để truy cập các thuộc tính và phương thức của object đó.

class Car:
def __init__(self, brand, model):
self.brand = brand
self.model = model

def get_model(self):
print(f"Model: {self.model}")

my_car = Car("Toyota", "Camry")
my_car.get_model() # Camry

4 - Phương thức của class

    Phương thức (method) là các hàm được định nghĩa trong class để mô tả hành vi của đối tượng. Bạn có thể phân loại:

  • Instance method: hoạt động trên từng đối tượng, sẽ bắt buộc có một tham số là self.
  • Class method: hoạt động ở mức class, dùng decorator @classmethod.
  • Static method: không phụ thuộc vào class hay instance, dùng @staticmethod.

class Example:
counter = 0

def __init__(self):
Example.counter += 1

@classmethod
def get_count(cls):
return cls.counter

@staticmethod
def info():
print("This is a static method.")

e1 = Example()
e2 = Example()
print(Example.get_count()) # 2
Example.info()

    Các Instance method cũng có thể gọi lần nhau bằng cách sử dụng từ khóa self.

class Car:
def __init__(self, brand, model):
self.brand = brand
self.model = model
self.speed = 0

def get_model(self):
print(f"Model: {self.model}")

def start_engine(self):
print(f"{self.brand} {self.model} engine started.")
# Gọi method khác qua self
self.show_status()

def accelerate(self, amount):
self.speed += amount
print(f"{self.brand} {self.model} is now at {self.speed} km/h.")
# Gọi method khác trong cùng class
self.show_status()

def show_status(self):
print(f"→ Current speed: {self.speed} km/h")


my_car = Car("Toyota", "Camry")
my_car.start_engine() # start_engine gọi self.show_status()
my_car.accelerate(50) # accelerate gọi self.show_status()

5 - Thuộc tính của đối tượng

    Thuộc tính có thể được truy cập và thay đổi trong runtime. Bạn có thể dùng hasattr(), getattr(), setattr(), và delattr() để thao tác động.

  1. class Car:
  2. def __init__(self, brand, model):
  3. self.brand = brand
  4. self.model = model
  5. self.speed = 0

  6. def get_model(self):
  7. print(f"Model: {self.model}")

  8. def accelerate(self, amount):
  9. self.speed += amount
  10. print(f"{self.brand} {self.model} is now running at {self.speed} km/h.")


  11. # --- Tạo object ---
  12. my_car = Car("Toyota", "Camry")

  13. # --- 1️⃣ Kiểm tra xem thuộc tính có tồn tại không ---
  14. if hasattr(my_car, "brand"):
  15. print("✅ Attribute 'brand' exists:", my_car.brand)
  16. else:
  17. print("❌ Attribute 'brand' does not exist")

  18. # --- 2️⃣ Lấy giá trị thuộc tính bằng getattr() ---
  19. model_name = getattr(my_car, "model", "Unknown")
  20. print("🚗 Model:", model_name)

  21. # --- 3️⃣ Gán thêm một thuộc tính mới bằng setattr() ---
  22. setattr(my_car, "color", "White")
  23. print("🎨 Added attribute 'color':", my_car.color)

  24. # --- 4️⃣ Gọi method động bằng getattr() ---
  25. method = getattr(my_car, "accelerate", None)
  26. if callable(method):
  27. method(40) # Gọi method accelerate(40)

  28. # --- 5️⃣ Xóa thuộc tính bằng delattr() ---
  29. if hasattr(my_car, "color"):
  30. delattr(my_car, "color")
  31. print("🧽 Attribute 'color' deleted.")

  32. # --- 6️⃣ Thử truy cập lại thuộc tính đã xóa ---
  33. print("Color exists?", hasattr(my_car, "color"))

6. Một số khái niệm quan trọng

Getter and Setter Methods

    Getter và Setter cung cấp cách truy cập có kiểm soát đến thuộc tính của đối tượng. Chúng giúp đóng gói dữ liệu (encapsulation) và ngăn việc thay đổi trực tiếp các biến nội bộ. Trong Python, ta dùng @property @<property>.setter để cài đặt getter và setter.

  1. class Car:
  2. def __init__(self, brand, model):
  3. self._brand = brand # Dấu gạch dưới _ cho biết thuộc tính là "private"
  4. self._model = model

  5. # Getter cho brand
  6. @property
  7. def brand(self):
  8. print("Getting brand...")
  9. return self._brand

  10. # Setter cho brand
  11. @brand.setter
  12. def brand(self, value):
  13. print("Setting brand...")
  14. if not isinstance(value, str):
  15. raise ValueError("Brand must be a string.")
  16. self._brand = value

  17. # Getter cho model
  18. @property
  19. def model(self):
  20. return self._model

  21. # Setter cho model
  22. @model.setter
  23. def model(self, value):
  24. if len(value) < 2:
  25. raise ValueError("Model name is too short.")
  26. self._model = value


  27. # --- Sử dụng ---
  28. my_car = Car("Toyota", "Camry")

  29. print(my_car.brand) # Tự động gọi getter
  30. my_car.brand = "Honda" # Tự động gọi setter
  31. print(my_car.brand)

  32. # Thử setter lỗi
  33. try:
  34. my_car.brand = 123 # Không hợp lệ
  35. except ValueError as e:
  36. print("Error:", e)

💡 Giải thích:

  • __init__: Hàm khởi tạo của class, tạo hai thuộc tính private là _brand và _model. Dấu gạch dưới (_) thể hiện rằng các thuộc tính này không nên truy cập trực tiếp từ bên ngoài class.
  • @property: Dùng để định nghĩa getter cho thuộc tính brand. Khi gọi my_car.brand, Python tự động gọi hàm brand(self) thay vì truy cập trực tiếp _brand.
  • @brand.setter: Dùng để định nghĩa setter cho thuộc tính brand. Khi gán my_car.brand = "Honda", Python sẽ gọi brand(self, value) để kiểm tra và cập nhật giá trị. Trong ví dụ, setter kiểm tra kiểu dữ liệu phải là str, nếu không sẽ raise ValueError.
  • @property (cho model): Định nghĩa getter cho model, cho phép đọc my_car.model mà không cần gọi hàm.
  • @model.setter: Định nghĩa setter cho model. Setter kiểm tra độ dài của chuỗi, nếu nhỏ hơn 2 ký tự sẽ raise lỗi ValueError("Model name is too short.").
  • self._brand và self._model: Là các biến nội bộ (private) thực sự lưu trữ dữ liệu của object. Getter và setter hoạt động như “cửa kiểm soát” truy cập đến các biến này.


Method Overriding

    Method Overriding (ghi đè phương thức) xảy ra khi subclass định nghĩa lại một phương thức đã có trong superclass. Điều này cho phép mở rộng hoặc thay đổi hành vi kế thừa.

  1. class Car:
  2. def __init__(self, brand, model):
  3. self.brand = brand
  4. self.model = model

  5. def start_engine(self):
  6. print(f"{self.brand} {self.model}: Engine started with a key.")


  7. # Class con kế thừa từ Car
  8. class ElectricCar(Car):
  9. def __init__(self, brand, model, battery_capacity):
  10. super().__init__(brand, model)
  11. self.battery_capacity = battery_capacity

  12. # 🔁 Overriding method từ class cha
  13. def start_engine(self):
  14. print(f"{self.brand} {self.model}: Powering on silently (battery: {self.battery_capacity} kWh).")


  15. # --- Sử dụng ---
  16. car1 = Car("Toyota", "Camry")
  17. car2 = ElectricCar("Tesla", "Model 3", 75)

  18. car1.start_engine() # Gọi method của class Car
  19. car2.start_engine() # Gọi method bị ghi đè trong class ElectricCar

    Trong đoạn code trên, class Car là class cha, định nghĩa phương thức start_engine() — giả lập xe dùng động cơ xăng. class ElectricCar(Car) là class con, kế thừa tất cả thuộc tính và phương thức của Car.

    Dòng super().__init__(brand, model) gọi hàm khởi tạo của class cha để tránh lặp code.

  • def start_engine(self): (trong ElectricCar): Đây là method overriding.
    Class ElectricCar định nghĩa lại phương thức start_engine() có cùng tên với class Car, nhưng hành vi khác (không dùng chìa, mà dùng pin).

    Khi gọi car2.start_engine(), Python ưu tiên method trong class con → method của Car bị ghi đè. Nếu vẫn muốn gọi method của class cha, có thể dùng trong class con.

super().start_engine()


Static Methods và Class Methods

    Cả hai loại phương thức này đều gắn với class thay vì instance:

  • Static Method: không truy cập instance hay class, dùng @staticmethod.
  • Class Method: truy cập class thông qua tham số cls, dùng @classmethod.
  1. class Car:
  2. total_cars = 0 # Thuộc tính class (dùng chung cho tất cả đối tượng)

  3. def __init__(self, brand, model):
  4. self.brand = brand
  5. self.model = model
  6. Car.total_cars += 1

  7. @staticmethod
  8. def general_info():
  9. """Static Method: Không truy cập self hoặc cls"""
  10. print("Cars are vehicles used for transportation.")

  11. @classmethod
  12. def show_total_cars(cls):
  13. """Class Method: Làm việc với thuộc tính class"""
  14. print(f"Total cars created: {cls.total_cars}")


  15. # Sử dụng
  16. car1 = Car("Toyota", "Camry")
  17. car2 = Car("Honda", "Civic")

  18. Car.general_info() # Static method
  19. Car.show_total_cars() # Class method

Abstract Classes và Interfaces

    Abstract Class cung cấp "mẫu" cho các lớp con kế thừa, ép buộc chúng phải cài đặt các phương thức nhất định. Python sử dụng module abc để định nghĩa lớp trừu tượng (abstract class).

from abc import ABC, abstractmethod

class Animal(ABC):
    @abstractmethod
    def sound(self):
        pass

class Dog(Animal):
    def sound(self):
        print("Woof")

dog = Dog()
dog.sound()  # Woof

Giải thích:

  • ABC: class cơ sở cho mọi abstract class.
  • @abstractmethod: khai báo phương thức phải được override.
  • Dog triển khai lại sound() — nếu không, Python sẽ báo lỗi khi tạo instance.

Class Variables vs Instance Variables

    Phân biệt rõ giữa:

  • Class Variable: dùng chung cho mọi instance.
  • Instance Variable: riêng biệt cho từng đối tượng.
class Dog:
    species = "Canine"  # Class variable

    def __init__(self, name, age):
        self.name = name  # Instance variable
        self.age = age

dog1 = Dog("Buddy", 3)
dog2 = Dog("Lucy", 2)

print(dog1.species)  # Canine
print(dog2.name)     # Lucy

Giải thích:

  • species: chia sẻ giữa mọi đối tượng Dog.
  • name, age: giá trị riêng của từng instance.
  • dog1.speciesdog2.name minh họa sự khác biệt rõ ràng.

7 - Tổng kết

Khái niệm Ý nghĩa Ví dụ
Class Bản thiết kế cho các object class Dog:
Object Thể hiện cụ thể của class dog1 = Dog()
__init__() Hàm khởi tạo đối tượng def __init__(...)
self Tham chiếu chính đối tượng hiện tại self.name = ...
Phương thức Hành vi của đối tượng def bark(self):

>>>>>> Follow ngay <<<<<<<

Để nhận được những bài học miễn phí mới nhất nhé 😊
Chúc các bạn học tập tốt 😊

Nguyễn Văn Nghĩa

Mình là một người thích học hỏi và chia sẻ các kiến thức về Nhúng IOT.

Đăng nhận xét

Mới hơn Cũ hơn
//