Bài 17.3. Làm việc với lớp và đối tượng trong Python

Bài 17.3. Làm việc với lớp và đối tượng trong Python
Bạn có thể sử dụng các lớp để đại diện cho nhiều tình huống thực tế. Một khi bạn viết một lớp, bạn sẽ dành phần lớn thời gian làm việc với các thể hiện được tạo từ lớp đó. Một trong những nhiệm vụ đầu tiên bạn sẽ muốn làm là thay đổi các thuộc tính liên quan đến một thể hiện cụ thể. Bạn có thể thay đổi các thuộc tính của một thể hiện trực tiếp hoặc viết các phương thức cập nhật các thuộc tính theo cách cụ thể.
Lớp Car
Hãy viết một lớp mới đại diện cho một chiếc xe hơi. Lớp của chúng ta sẽ lưu trữ thông tin về loại xe mà chúng ta đang làm việc, và nó sẽ có một phương thức tóm tắt thông tin này:
class Car:
"""Một nỗ lực đơn giản để đại diện cho một chiếc xe hơi."""
def __init__(self, make, model, year):
"""Khởi tạo các thuộc tính để mô tả một chiếc xe hơi."""
self.make = make
self.model = model
self.year = year
def get_descriptive_name(self):
"""Trả về một tên mô tả được định dạng gọn gàng."""
long_name = f"{self.year} {self.make} {self.model}"
return long_name.title()
my_new_car = Car('audi', 'a4', 2024)
print(my_new_car.get_descriptive_name())
Trong lớp Car
, chúng ta định nghĩa phương thức __init__()
với tham số self
đầu tiên, giống như chúng ta đã làm với lớp Dog
. Chúng ta cũng cung cấp cho nó ba tham số khác: make
, model
, và year
. Phương thức __init__()
nhận các tham số này và gán chúng cho các thuộc tính sẽ được liên kết với các thể hiện được tạo từ lớp này. Khi chúng ta tạo một thể hiện mới của Car
, chúng ta sẽ cần chỉ định một make
, model
, và year
cho thể hiện của chúng ta.
Chúng ta định nghĩa một phương thức gọi là get_descriptive_name()
đặt năm, hãng và mẫu xe vào một chuỗi mô tả gọn gàng về chiếc xe. Điều này sẽ giúp chúng ta không phải in giá trị của từng thuộc tính riêng lẻ. Để làm việc với các giá trị thuộc tính trong phương thức này, chúng ta sử dụng self.make
, self.model
, và self.year
. Bên ngoài lớp, chúng ta tạo một thể hiện từ lớp Car
và gán nó cho biến my_new_car
. Sau đó, chúng ta gọi get_descriptive_name()
để hiển thị loại xe mà chúng ta có:
2024 Audi A4
Để làm cho lớp thú vị hơn, hãy thêm một thuộc tính thay đổi theo thời gian. Chúng ta sẽ thêm một thuộc tính lưu trữ tổng số dặm của xe.
Đặt giá trị mặc định cho một thuộc tính
Khi một thể hiện được tạo, các thuộc tính có thể được định nghĩa mà không cần được truyền vào dưới dạng tham số. Các thuộc tính này có thể được định nghĩa trong phương thức __init__()
, nơi chúng được gán một giá trị mặc định.
Hãy thêm một thuộc tính gọi là odometer_reading
luôn bắt đầu với giá trị 0. Chúng ta cũng sẽ thêm một phương thức read_odometer()
giúp chúng ta đọc số dặm của mỗi chiếc xe:
class Car:
def __init__(self, make, model, year):
"""Khởi tạo các thuộc tính để mô tả một chiếc xe hơi."""
self.make = make
self.model = model
self.year = year
self.odometer_reading = 0
def get_descriptive_name(self):
"""Trả về một tên mô tả được định dạng gọn gàng."""
long_name = f"{self.year} {self.make} {self.model}"
return long_name.title()
def read_odometer(self):
"""In ra một câu cho biết số dặm của xe."""
print(f"This car has {self.odometer_reading} miles on it.")
my_new_car = Car('audi', 'a4', 2024)
print(my_new_car.get_descriptive_name())
my_new_car.read_odometer()
Lần này, khi Python gọi phương thức __init__()
để tạo một thể hiện mới, nó lưu trữ các giá trị make
, model
, và year
dưới dạng các thuộc tính, giống như trong ví dụ trước. Sau đó, Python tạo một thuộc tính mới gọi là odometer_reading
và
Bài tập: Hình học
Mô tả:
Tạo các class hình học để:
- Tính diện tích hình chữ nhật và hình vuông
- Tính chu vi hình chữ nhật và hình vuông
- Quản lý các hình bằng ID
Input:
- Dòng 1: Số nguyên N (số lệnh)
- N dòng tiếp theo: Các lệnh theo định dạng:
- RECT w h: tạo hình chữ nhật
- SQUARE s: tạo hình vuông
- AREA id: tính diện tích
- PERI id: tính chu vi
Output:
- RECT/SQUARE: "Created shape id={id}"
- AREA: Diện tích của hình
- PERI: Chu vi của hình
Ví dụ:
Input:
4
RECT 5 3
SQUARE 4
AREA 1
PERI 2
Output:
Created shape id=1
Created shape id=2
15
16
Code Python:
class Shape:
next_id = 1
def __init__(self):
self.id = Shape.next_id
Shape.next_id += 1
def area(self):
pass
def perimeter(self):
pass
class Rectangle(Shape):
def __init__(self, width, height):
super().__init__()
self.width = width
self.height = height
def area(self):
return self.width * self.height
def perimeter(self):
return 2 * (self.width + self.height)
class Square(Shape):
def __init__(self, side):
super().__init__()
self.side = side
def area(self):
return self.side * self.side
def perimeter(self):
return 4 * self.side
def process_commands():
shapes = {}
n = int(input())
for _ in range(n):
cmd = input().split()
if cmd[0] == "RECT":
shape = Rectangle(int(cmd[1]), int(cmd[2]))
shapes[shape.id] = shape
print(f"Created shape id={shape.id}")
elif cmd[0] == "SQUARE":
shape = Square(int(cmd[1]))
shapes[shape.id] = shape
print(f"Created shape id={shape.id}")
elif cmd[0] == "AREA":
id = int(cmd[1])
print(shapes[id].area())
elif cmd[0] == "PERI":
id = int(cmd[1])
print(shapes[id].perimeter())
if __name__ == "__main__":
process_commands()
Giải thích:
Class Shape (lớp cha):
- Quản lý ID tự động tăng
- Định nghĩa phương thức area() và perimeter()
Class Rectangle (lớp con):
- Kế thừa từ Shape
- Tính diện tích: width * height
- Tính chu vi: 2 * (width + height)
Class Square (lớp con):
- Kế thừa từ Shape
- Tính diện tích: side * side
- Tính chu vi: 4 * side
Xử lý lệnh:
- RECT: tạo hình chữ nhật mới
- SQUARE: tạo hình vuông mới
- AREA: in diện tích
- PERI: in chu vi
Comments