4. Python 面向对象编程
4.2 继承与多态
4.2.1 继承的基本概念
在面向对象编程(OOP)中,继承是一种机制,允许一个类(子类)从另一个类(父类或基类)继承属性和方法。通过继承,子类可以复用父类的代码,并且可以在不修改父类的情况下扩展或修改其行为。
Python 中的继承语法非常简单,只需在定义子类时在类名后的括号中指定父类即可。例如:
class Animal:
def __init__(self, name):
self.name = name
def speak(self):
return f"{self.name} makes a sound."
class Dog(Animal):
def speak(self):
return f"{self.name} barks."
在这个例子中,Dog 类继承了 Animal 类,并且重写了 speak 方法。
4.2.2 单继承与多继承
Python 支持单继承和多继承。单继承是指一个子类只能继承一个父类,而多继承则允许一个子类继承多个父类。
单继承:子类只继承一个父类。这是最常见的继承方式,代码结构清晰,易于维护。
多继承:子类可以继承多个父类。多继承虽然提供了更大的灵活性,但也可能导致代码复杂性和潜在的冲突问题。Python 使用 C3 线性化算法来解决多继承中的方法解析顺序(MRO)问题。
class A:
def method(self):
return "A"
class B:
def method(self):
return "B"
class C(A, B):
pass
c = C()
print(c.method()) # 输出 "A",因为 A 在 MRO 中排在 B 前面
4.2.3 方法重写与 super() 函数
子类可以重写父类的方法,以提供特定的实现。如果子类需要调用父类的方法,可以使用 super() 函数。super() 函数返回一个代理对象,允许子类调用父类的方法。
class Animal:
def __init__(self, name):
self.name = name
def speak(self):
return f"{self.name} makes a sound."
class Dog(Animal):
def speak(self):
return super().speak() + " But it barks."
在这个例子中,Dog 类重写了 speak 方法,并通过 super() 调用了父类的 speak 方法。
4.2.4 多态的概念与实现
多态是面向对象编程的另一个重要特性,它允许不同的类对同一方法有不同的实现。多态性使得代码更加灵活和可扩展。
在 Python 中,多态性通常通过方法重写来实现。由于 Python 是动态类型语言,多态性在运行时自动处理。
class Cat(Animal):
def speak(self):
return f"{self.name} meows."
def animal_sound(animal):
print(animal.speak())
dog = Dog("Buddy")
cat = Cat("Whiskers")
animal_sound(dog) # 输出 "Buddy makes a sound. But it barks."
animal_sound(cat) # 输出 "Whiskers meows."
在这个例子中,animal_sound 函数可以接受任何 Animal 类的子类对象,并调用其 speak 方法。由于 Dog 和 Cat 类都重写了 speak 方法,因此它们的行为不同。
4.2.5 抽象基类与接口
Python 提供了 abc 模块来定义抽象基类(Abstract Base Classes, ABCs)。抽象基类是一种特殊的类,不能直接实例化,只能被继承。抽象基类可以定义抽象方法,子类必须实现这些方法。
from abc import ABC, abstractmethod
class Shape(ABC):
@abstractmethod
def area(self):
pass
class Circle(Shape):
def __init__(self, radius):
self.radius = radius
def area(self):
return 3.14 * self.radius ** 2
circle = Circle(5)
print(circle.area()) # 输出 78.5
在这个例子中,Shape 是一个抽象基类,Circle 类继承了 Shape 并实现了 area 方法。抽象基类可以用于定义接口,确保子类实现了特定的方法。
4.2.6 总结
继承与多态是面向对象编程的核心概念。通过继承,子类可以复用父类的代码,并且可以通过方法重写和 super() 函数来扩展或修改父类的行为。多态性使得代码更加灵活,允许不同的类对同一方法有不同的实现。抽象基类则提供了一种定义接口的方式,确保子类实现了特定的方法。
理解这些概念对于编写高效、可维护的面向对象代码至关重要。在实际开发中,合理使用继承与多态可以大大提高代码的复用性和可扩展性。
