继承和多态

Python面向对象编程:继承与多态教程

1. 继承基础

继承是面向对象编程的重要特性,允许我们基于现有类创建新类。新类(子类)可以继承父类的属性和方法,同时可以添加或修改功能。

1.1 基本语法

class ParentClass:
    # 父类定义
    pass

class ChildClass(ParentClass):
    # 子类定义
    pass

1.2 继承示例

class Animal:
    def __init__(self, name):
        self.name = name
        
    def speak(self):
        print(f"{self.name} makes a sound")

class Dog(Animal):
    def speak(self):
        print(f"{self.name} barks")

class Cat(Animal):
    def speak(self):
        print(f"{self.name} meows")

2. 继承的优势

2.1 代码复用

子类自动获得父类的所有方法和属性,无需重复编写:

animal = Animal("Generic")
animal.speak()  # Generic makes a sound

dog = Dog("Buddy")
dog.speak()     # Buddy barks

cat = Cat("Whiskers")
cat.speak()     # Whiskers meows

2.2 方法重写

子类可以覆盖(override)父类的方法,提供特定实现:

class Bird(Animal):
    def speak(self):
        print(f"{self.name} chirps")
        
    def fly(self):
        print(f"{self.name} is flying")

3. 多态性

多态是指不同类的对象对同一消息做出不同响应的能力。

3.1 多态示例

def animal_speak(animal):
    animal.speak()

animals = [Dog("Rex"), Cat("Mittens"), Bird("Tweety")]

for animal in animals:
    animal_speak(animal)

输出:

Rex barks
Mittens meows
Tweety chirps

3.2 开闭原则

多态支持"开闭原则":

  • 对扩展开放:可以添加新的子类而不影响现有代码
  • 对修改封闭:不需要修改依赖父类的函数

4. 继承层次

Python支持多重继承,形成继承树:

        object
       /      \
   Animal    Plant
   /    \    /    \
Dog   Cat Tree  Flower

5. 类型检查

使用isinstance()issubclass()检查对象和类的关系:

dog = Dog("Buddy")

print(isinstance(dog, Dog))    # True
print(isinstance(dog, Animal)) # True
print(issubclass(Dog, Animal)) # True

6. 鸭子类型

Python作为动态语言,采用"鸭子类型"(Duck Typing):

  • 不强制要求继承关系
  • 只关心对象是否有需要的方法
class Car:
    def speak(self):
        print("Vroom vroom!")

def make_it_speak(thing):
    thing.speak()

make_it_speak(Dog("Spot"))  # Spot barks
make_it_speak(Car())        # Vroom vroom!

7. 最佳实践

  1. 优先使用组合而非继承:除非有明显的"is-a"关系
  2. 避免多重继承:可能导致复杂的继承关系
  3. 使用抽象基类(ABC):定义接口规范
  4. 遵循Liskov替换原则:子类应该能替换父类而不破坏程序

8. 抽象基类示例

from abc import ABC, abstractmethod

class Shape(ABC):
    @abstractmethod
    def area(self):
        pass
        
    @abstractmethod
    def perimeter(self):
        pass

class Rectangle(Shape):
    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)

9. 总结

继承和多态是面向对象编程的核心概念:

  • 继承:实现代码复用和层次化设计
  • 多态:提高代码的灵活性和可扩展性
  • 鸭子类型:Python特有的灵活设计方式

合理使用这些特性可以创建出更灵活、更易维护的代码结构。