9.Python面向对象三大特性:封装、继承与多态详解

150 阅读4分钟

一、封装(Encapsulation)

1. 核心概念

  • 数据隐藏:将对象的状态(属性)和行为(方法)包装在类内部
  • 访问控制:通过权限修饰控制对类成员的访问
  • 优点:提高安全性、降低耦合度、增强可维护性

2. Python实现方式

(1) 命名约定

  • _single_leading_underscore:约定私有成员(非强制)
  • __double_leading_underscore:名称修饰(Name Mangling)
  • __double_ends__:魔术方法
class BankAccount:
    def __init__(self, owner, balance):
        self._owner = owner       # 保护成员
        self.__balance = balance  # 私有成员(实际被修饰为_BankAccount__balance)
    
    def get_balance(self):        # 访问器方法
        return self.__balance
    
    def deposit(self, amount):    # 业务逻辑封装
        if amount > 0:
            self.__balance += amount

acc = BankAccount("Alice", 1000)
print(acc._owner)              # 可以访问但约定不推荐
# print(acc.__balance)         # 报错:AttributeError
print(acc._BankAccount__balance)  # 1000(强制访问)

(2) 属性装饰器(推荐)

class Temperature:
    def __init__(self, celsius):
        self._celsius = celsius
    
    @property
    def celsius(self):          # Getter
        return self._celsius
    
    @celsius.setter
    def celsius(self, value):   # Setter
        if value < -273.15:
            raise ValueError("温度不能低于绝对零度")
        self._celsius = value
    
    @property
    def fahrenheit(self):      # 计算属性
        return self._celsius * 1.8 + 32

temp = Temperature(25)
print(temp.fahrenheit)  # 77.0
temp.celsius = 30       # 通过验证的赋值

二、继承(Inheritance)

1. 继承机制

  • 基类(父类):被继承的类
  • 派生类(子类):继承的类
  • 优点:代码复用、扩展功能、实现多态基础

2. 继承类型

(1) 单继承

class Animal:
    def __init__(self, name):
        self.name = name
    
    def speak(self):
        raise NotImplementedError("子类必须实现此方法")

class Dog(Animal):
    def speak(self):   # 方法重写
        return "汪汪!"

class Cat(Animal):
    def speak(self):
        return "喵~"

d = Dog("阿黄")
print(d.speak())  # 汪汪!

(2) 多继承

class Flyable:
    def fly(self):
        return "飞行中..."

class Swimmable:
    def swim(self):
        return "游泳中..."

class Duck(Flyable, Swimmable):
    pass

duck = Duck()
print(duck.fly())  # 飞行中...
print(duck.swim()) # 游泳中...

3. 方法解析顺序(MRO)

class A:
    def test(self):
        print("A")

class B(A):
    def test(self):
        print("B")

class C(A):
    def test(self):
        print("C")

class D(B, C):
    pass

print(D.mro())  
# [<class '__main__.D'>, <class '__main__.B'>, 
#  <class '__main__.C'>, <class '__main__.A'>, <class 'object'>]

d = D()
d.test()  # 输出B

4. super()函数

class Parent:
    def __init__(self, name):
        self.name = name
        print("Parent初始化完成")

class Child(Parent):
    def __init__(self, name, age):
        super().__init__(name)  # 调用父类构造
        self.age = age
        print("Child初始化完成")

c = Child("小明", 10)
# Parent初始化完成
# Child初始化完成

三、多态(Polymorphism)

1. 实现原理

  • 鸭子类型:"当看到一只鸟走起来像鸭子、游泳像鸭子、叫起来也像鸭子,那么这只鸟就可以被称为鸭子"
  • 核心思想:关注对象行为而非具体类型

2. Python实现方式

class Circle:
    def draw(self):
        print("绘制圆形")

class Rectangle:
    def draw(self):
        print("绘制矩形")

def render_shape(shape):  # 多态函数
    shape.draw()

shapes = [Circle(), Rectangle()]
for s in shapes:
    render_shape(s)
# 绘制圆形
# 绘制矩形

3. 结合抽象基类

from abc import ABC, abstractmethod

class Shape(ABC):      # 抽象基类
    @abstractmethod
    def area(self):
        pass

class Square(Shape):
    def __init__(self, side):
        self.side = side
    
    def area(self):
        return self.side ** 2

class Circle(Shape):
    def __init__(self, radius):
        self.radius = radius
    
    def area(self):
        return 3.14 * self.radius ** 2

def print_area(shape: Shape):
    print(f"图形面积:{shape.area()}")

shapes = [Square(5), Circle(3)]
for s in shapes:
    print_area(s)
# 图形面积:25
# 图形面积:28.26

四、综合应用案例

class Employee:
    def __init__(self, name, salary):
        self._name = name
        self.__salary = salary
    
    @property
    def salary(self):
        return self.__salary
    
    def annual_bonus(self):
        return self.__salary * 0.1

class Manager(Employee):
    def annual_bonus(self):  # 方法重写
        return super().annual_bonus() + 5000

class Developer(Employee):
    def __init__(self, name, salary, language):
        super().__init__(name, salary)
        self.language = language
    
    def annual_bonus(self):
        return self.salary * 0.15

def calculate_total_bonus(employees):  # 多态应用
    return sum(emp.annual_bonus() for emp in employees)

# 创建实例
team = [
    Manager("张经理", 20000),
    Developer("王程序员", 15000, "Python"),
    Developer("李工程师", 18000, "Java")
]

total = calculate_total_bonus(team)
print(f"年度总奖金:{total}元")  # 20000*0.1+5000 + 15000*0.15 + 18000*0.15 = 2000+5000+2250+2700=11950

五、最佳实践与注意事项

  1. 封装原则
  • 优先使用属性装饰器而非直接暴露属性
  • 私有成员仅用于内部实现细节
  • 保持类的单一职责原则
  1. 继承建议
  • 避免超过3层的继承层级
  • 谨慎使用多继承,优先使用组合
  • 使用super()保证初始化顺序
  1. 多态技巧
  • 依赖抽象而非具体实现
  • 使用鸭子类型替代复杂的类型检查
  • 合理运用ABC模块定义接口
  1. 常见误区
  • 过度使用私有成员(__前缀)
  • 错误的方法解析顺序导致bug
  • 通过类型判断破坏多态性(如大量使用isinstance

六、总结提升

  1. 封装是面向对象的安全屏障
  2. 继承是实现代码复用的双刃剑
  3. 多态是系统扩展性的关键
  4. Python通过灵活的语法实现三大特性:
    • 命名约定实现封装
    • MRO机制处理复杂继承
    • 鸭子类型支持天然多态

掌握这些核心概念后,可以:

  • 设计更健壮的类结构
  • 编写可扩展的模块化代码
  • 构建易于维护的系统架构
  • 更好地理解标准库和第三方库的设计思想

建议通过实际项目练习,逐步体会不同场景下三大特性的应用技巧,最终形成面向对象的编程思维。