← Python 学习路线(共 8 章)

第 7 章 面向对象

red wenzi · 2026-09-15 · 编程语言 · Python · 📖 预计阅读 10 分钟 · 共 2 道练习
🎯 本章你会学到:class、self、继承、dataclass:够用就好的面向对象。建议边读边敲,每节练习先自己做,再展开答案对照。

Python 的面向对象比 Java 轻:没有接口关键字、没有访问修饰符(靠下划线约定)、方法第一个参数永远是 self。写小东西时,一个 dataclass 往往就够了。

类、属性与方法

dataclass
from dataclasses import dataclass

@dataclass
class Student:
    name: str
    score: int = 0

    def passed(self):
        return self.score >= 60

s = Student("Ann", 90)
print(s)
print(s.passed(), Student("Bob").passed())
运行结果
Student(name='Ann', score=90)
True False

继承与方法重写

继承与多态
class Shape:
    def area(self):
        raise NotImplementedError

class Circle(Shape):
    def __init__(self, r):
        self.r = r

    def area(self):
        return 3.14159265 * self.r ** 2

class Square(Shape):
    def __init__(self, side):
        self.side = float(side)

    def area(self):
        return self.side ** 2

shapes = [Circle(1), Square(2)]
print(f"{sum(s.area() for s in shapes):.2f}")
print([round(s.area(), 2) for s in shapes])
运行结果
7.14
[3.14, 4.0]

父类 ShapeareaNotImplementedError,子类各自实现。遍历 shapes 时调用 s.area() 会自动选到对应实现——这就是多态,和 Java 的写法几乎一样,只是不需要接口声明。

⚠️ 易错点 类属性是所有实例共享的;把可变对象写成类属性(如 items = [])会导致所有实例互相污染,应该放在 __init__ 里。
⚠️ 易错点 __init__ 不是“构造函数”而是初始化方法;真正的构造由 __new__ 完成——日常只需要关注 __init__

✍️ 本节练习

7.1必做矩形类

写一个 Rectangle 类(宽、高),提供 area()perimeter() 方法;读入宽高输出面积与周长(2 位小数)。

输入 一行两个实数:宽 高。

输出 两行:area=perimeter=(2 位小数)。

样例输入
3 4
样例输出
area=12.00
perimeter=14.00

💡 提示 构造器里存 self.widthself.height,两个方法返回计算值。

✅ 查看参考答案与解析
class Rectangle:
    def __init__(self, width, height):
        self.width = width
        self.height = height

    def area(self):
        return self.width * self.height

    def perimeter(self):
        return 2 * (self.width + self.height)

w, h = map(float, input().split())
r = Rectangle(w, h)
print(f"area={r.area():.2f}")
print(f"perimeter={r.perimeter():.2f}")

解析 用 map(float, input().split()) 一次读入两个浮点数,然后直接构造对象。

7.2挑战银行账户(异常驱动)

BankAccount 类(余额、deposit、withdraw)。取款超过余额时抛 ValueError。读入初始余额和若干操作,越界取款输出 error: insufficient funds,最后输出余额(2 位小数)。

输入 第一行初始余额;第二行操作数 n;接下来 n 行 + 金额- 金额

输出 越界时输出错误行;最后一行 balance=余额

样例输入
100
3
+ 50
- 30
- 500
样例输出
error: insufficient funds
balance=120.00

💡 提示 在类里判断并 raise ValueError("insufficient funds"),调用处 try/except 打印。

✅ 查看参考答案与解析
class BankAccount:
    def __init__(self, balance=0.0):
        self.balance = balance

    def deposit(self, amount):
        self.balance += amount

    def withdraw(self, amount):
        if amount > self.balance:
            raise ValueError("insufficient funds")
        self.balance -= amount

account = BankAccount(float(input()))
for _ in range(int(input())):
    op, amount = input().split()
    try:
        if op == "+":
            account.deposit(float(amount))
        else:
            account.withdraw(float(amount))
    except ValueError as e:
        print(f"error: {e}")

print(f"balance={account.balance:.2f}")

解析 把“能不能取”这条规则放进类里,调用方只负责捕获——这就是把业务规则封装在对象内部的写法。

📚 本文概念都在知识大全:

Python · pip 与虚拟环境 · 列表/字典/集合 · 推导式 · f-string · 异常处理 · dataclass · pandas · 模块与包