Python面向对象:class类与对象,3个案例讲透封装与继承


Python面向对象:class类与对象,3个案例讲透封装与继承

前面的代码都是"写一堆函数 + 操作数据"。但当程序变大,这种方式会变得很难管理。面向对象编程(OOP)用"把数据和操作打包"的方式,让代码更好组织。这篇文章用3个案例讲清楚类和对象的核心概念。


一句话概括

这篇文章解决一个问题:学会用 class 定义类,理解封装和继承两个核心概念。


类和对象是什么

类(Class) :抽象的模板,比如"人"这个概念
对象(Object):具体的实例,比如"小明"这个具体的人

python 复制代码
# 定义一个"学生"类
class Student:
    # __init__ 是构造函数,创建对象时自动调用
    def __init__(self, name, score):
        self.name = name      # 实例属性
        self.score = score    # 实例属性
    
    def say_hello(self):      # 实例方法
        print(f"大家好,我叫{self.name}!")
    
    def get_grade(self):      # 实例方法
        if self.score >= 90:
            return "A"
        elif self.score >= 80:
            return "B"
        else:
            return "C"

# 创建对象(实例化)
s1 = Student("小明", 95)
s2 = Student("小红", 87)

# 调用对象的方法
s1.say_hello()        # 大家好,我叫小明!
print(s1.get_grade())  # A
print(s2.get_grade())  # B

init:构造函数

__init__ 在创建对象时自动调用,用来初始化对象的属性:

python 复制代码
class Person:
    def __init__(self, name, age):
        self.name = name  # 把name存到对象里
        self.age = age    # 把age存到对象里
        print(f"{self.name}出生了!")
    
    def introduce(self):
        print(f"我叫{self.name},今年{self.age}岁。")

p = Person("小明", 18)    # 输出:小明出生了!
p.introduce()             # 输出:我叫小明,今年18岁。

self 是什么

self 是指当前对象本身 ,类似于其他语言里的 this

python 复制代码
class Dog:
    def __init__(self, name):
        self.name = name
    
    def bark(self):
        # self.name 指的是这个对象自己的name
        print(f"{self.name}: 汪汪汪!")

dog1 = Dog("旺财")
dog2 = Dog("小白")

dog1.bark()  # 旺财: 汪汪汪!
dog2.bark()  # 小白: 汪汪汪!

案例1:银行账户系统

python 复制代码
class BankAccount:
    """银行账户类"""
    
    def __init__(self, owner, balance=0):
        self.owner = owner
        self.balance = balance
        print(f"为 {owner} 开户,初始余额:{balance}")
    
    def deposit(self, amount):
        """存款"""
        if amount > 0:
            self.balance += amount
            print(f"存款 {amount},余额 {self.balance}")
        else:
            print("存款金额必须为正!")
    
    def withdraw(self, amount):
        """取款"""
        if amount > self.balance:
            print(f"余额不足!当前余额:{self.balance}")
        elif amount <= 0:
            print("取款金额必须为正!")
        else:
            self.balance -= amount
            print(f"取款 {amount},余额 {self.balance}")
    
    def show_balance(self):
        """显示余额"""
        print(f"{self.owner} 的余额:{self.balance}")

# 测试
account = BankAccount("小明", 1000)
account.deposit(500)     # 存款 500,余额 1500
account.withdraw(200)    # 取款 200,余额 1300
account.withdraw(2000)   # 余额不足!当前余额:1300
account.show_balance()  # 小明 的余额:1300

继承:复用类

继承允许我们基于已有的类创建新类,新类自动拥有父类的属性和方法。

python 复制代码
# 父类
class Animal:
    def __init__(self, name):
        self.name = name
    
    def speak(self):
        raise NotImplementedError("子类必须实现speak方法")

# 子类:狗
class Dog(Animal):
    def speak(self):
        return f"{self.name}: 汪汪汪!"

# 子类:猫
class Cat(Animal):
    def speak(self):
        return f"{self.name}: 喵喵喵!"

# 子类:鸭子
class Duck(Animal):
    def speak(self):
        return f"{self.name}: 嘎嘎嘎!"

# 测试
animals = [Dog("旺财"), Cat("小白"), Duck("唐老鸭")]

for animal in animals:
    print(animal.speak())

输出:

复制代码
旺财: 汪汪汪!
小白: 喵喵喵!
唐老鸭: 嘎嘎嘎!

案例2:图形面积计算器

python 复制代码
import math

class Shape:
    """图形基类"""
    def area(self):
        raise NotImplementedError("子类必须实现area方法")

class Rectangle(Shape):
    """矩形"""
    def __init__(self, width, height):
        self.width = width
        self.height = height
    
    def area(self):
        return self.width * self.height

class Circle(Shape):
    """圆"""
    def __init__(self, radius):
        self.radius = radius
    
    def area(self):
        return math.pi * self.radius ** 2

class Triangle(Shape):
    """三角形"""
    def __init__(self, base, height):
        self.base = base
        self.height = height
    
    def area(self):
        return 0.5 * self.base * self.height

class Parallelogram(Shape):
    """平行四边形"""
    def __init__(self, base, height):
        self.base = base
        self.height = height
    
    def area(self):
        return self.base * self.height

# 测试
shapes = [
    Rectangle(5, 3),
    Circle(4),
    Triangle(6, 4),
    Parallelogram(5, 3),
]

for shape in shapes:
    print(f"{shape.__class__.__name__} 面积:{shape.area():.2f}")

# 输出:
# Rectangle 面积:15.00
# Circle 面积:50.27
# Triangle 面积:12.00
# Parallelogram 面积:15.00

案例3:电商订单系统

python 复制代码
class Product:
    """商品类"""
    def __init__(self, product_id, name, price):
        self.product_id = product_id
        self.name = name
        self.price = price
    
    def __repr__(self):
        return f"{self.name}(¥{self.price})"

class CartItem:
    """购物车项"""
    def __init__(self, product, quantity):
        self.product = product
        self.quantity = quantity
    
    @property
    def subtotal(self):
        """小计金额"""
        return self.product.price * self.quantity

class ShoppingCart:
    """购物车"""
    def __init__(self):
        self.items = []
    
    def add_item(self, product, quantity=1):
        """添加商品"""
        # 检查是否已存在
        for item in self.items:
            if item.product.product_id == product.product_id:
                item.quantity += quantity
                print(f"已更新 {product.name} 数量:{item.quantity}")
                return
        # 新增
        self.items.append(CartItem(product, quantity))
        print(f"已添加 {product.name} x {quantity}")
    
    def remove_item(self, product_id):
        """移除商品"""
        self.items = [item for item in self.items 
                      if item.product.product_id != product_id]
    
    @property
    def total(self):
        """总价"""
        return sum(item.subtotal for item in self.items)
    
    def show_cart(self):
        """显示购物车"""
        print("\n" + "=" * 40)
        print("购物车")
        print("=" * 40)
        for item in self.items:
            print(f"{item.product.name:<15} x {item.quantity:<3} = ¥{item.subtotal:.2f}")
        print("-" * 40)
        print(f"{'总计':<18} = ¥{self.total:.2f}")
        print("=" * 40)

# 测试
cart = ShoppingCart()

p1 = Product("P001", "iPhone", 6999)
p2 = Product("P002", "AirPods", 1299)
p3 = Product("P003", "MacBook", 9999)

cart.add_item(p1)      # 已添加 iPhone x 1
cart.add_item(p2, 2)  # 已添加 AirPods x 2
cart.add_item(p3)     # 已添加 MacBook x 1

cart.show_cart()

cart.remove_item("P002")
cart.show_cart()

常见问题FAQ

Q1:类属性 vs 实例属性

python 复制代码
class Dog:
    kind = "狗"  # 类属性,所有对象共享
    
    def __init__(self, name):
        self.name = name  # 实例属性,每个对象独有

dog1 = Dog("旺财")
dog2 = Dog("小白")

print(dog1.kind)  # 狗(类属性)
print(dog2.kind)  # 狗(类属性)
print(dog1.name)  # 旺财(实例属性)
print(dog2.name)  # 小白(实例属性)

Q2:私有属性(封装)

用双下划线开头的是"私有属性",外部不应该直接访问:

python 复制代码
class Person:
    def __init__(self, name, age):
        self.__name = name  # 私有属性(名字会被混淆)
        self.__age = age    # 私有属性
    
    def get_info(self):
        return f"{self.__name}, {self.__age}"

p = Person("小明", 18)
print(p.get_info())       # 小明, 18
print(p.__name)           # 报错!私有属性不能直接访问

Q3:str vs repr

python 复制代码
class Person:
    def __init__(self, name):
        self.name = name
    
    def __str__(self):
        """给用户看的字符串"""
        return f"Person: {self.name}"
    
    def __repr__(self):
        """给开发者看的字符串"""
        return f"Person(name='{self.name}')"

p = Person("小明")
print(str(p))    # Person: 小明
print(repr(p))  # Person(name='小明')

写在最后

这篇文章覆盖了面向对象的核心概念:

  • class 定义类
  • init 构造函数
  • self 当前对象
  • 继承:子类复用父类
  • 封装:私有属性保护数据

下一篇文章:Python 第一周复习,思维导图 + 10道练习题检测学习成果。


参考资料

相关推荐
计算机安禾2 小时前
【数据结构与算法】第13篇:栈(三):中缀表达式转后缀表达式及计算
c语言·开发语言·数据结构·c++·算法·链表
happymaker06262 小时前
servlet、jsp、请求转发、重定向的一些个人理解
java·开发语言·servlet
于先生吖2 小时前
国际版答题系统 JAVA 源码实战指南
java·开发语言
晓13132 小时前
【Python篇】——Anaconda安装与使用完全手册
python·conda
码界筑梦坊2 小时前
354-基于Python的全国水稻数据可视化分析系统
开发语言·python·信息可视化·数据分析·flask·bootstrap·毕业设计
码界筑梦坊2 小时前
336-基于Python的肺癌数据可视化分析预测系统
开发语言·python·信息可视化·数据分析·django·vue·毕业设计
AI科技星2 小时前
基于四维时空光速不变公设的量子几何与量子力学本质全维度推导验证
开发语言·人工智能·opencv·计算机视觉·数学建模·r语言
清水白石0082 小时前
《Python 性能优化实战:多进程并行 vs C/Rust/Cython 扩展的对比决策与团队落地指南》
python·spring·缓存
不会写DN2 小时前
Go 中最主流 JWT 库 jwt -go
开发语言·后端·golang