Python 面向对象进阶:继承与多态,让你的代码更优雅

239 阅读3分钟

一、继承:代码复用的利器

1.1 继承的概念

继承是面向对象编程中的一个基本概念,它允许一个类从另一个类继承属性和方法。通过继承,子类不仅可以复用父类的代码,还能对其进行扩展或修改。继承实现了代码的重用,使得程序结构更加清晰,维护更加方便。

1.2 Python中的继承

在 Python 中,继承是通过类定义时指定父类来实现的。语法如下:

class 父类:
    # 父类的属性和方法
    pass

class 子类(父类):
    # 子类可以访问父类的属性和方法
    pass

通过这种方式,子类可以访问父类的所有属性和方法,除非父类的某些方法被子类重写(覆盖)。

1.3 继承示例

我们来看一个简单的继承示例:

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

# 定义一个子类 Dog 继承 Animal
class Dog(Animal):
    def speak(self):
        return f"{self.name} barks"

# 定义另一个子类 Cat 继承 Animal
class Cat(Animal):
    def speak(self):
        return f"{self.name} meows"

# 创建对象
dog = Dog("Buddy")
cat = Cat("Whiskers")

print(dog.speak())  # 输出 Buddy barks
print(dog.run())  # 输出 Buddy is running...
print(cat.speak())  # 输出 Whiskers meows
print(cat.run())  # 输出 Whiskers is running...

在这个例子中,DogCat 类继承了 Animal 类,并重写了 speak 方法。通过继承,我们避免了重复编写 name 属性和基本的初始化方法,而将公共代码放到了父类 Animal 中。

1.4 多重继承

Python 支持多重继承,即一个子类可以继承多个父类。多重继承可以让子类拥有多个父类的属性和方法。

当遇到菱形问题(即子类中调用的某个方法,即在多个父类中都存在)时,不清楚super是哪个父类的时候,可以通过print(Dog.__mro__)或者print(Dog.mro())来查看继承顺序。具体的请关注Python多继承之广度优先C3算法,留待日后。

示例

class Flyable:
    def fly(self):
        return f"{self.name} is flying"
    

class Swimmable:
    def swim(self):
        return f"{self.name} is swimming"

class Duck(Animal, Flyable, Swimmable):
    pass

# 创建对象
duck = Duck("Donald")
print(duck.speak())  # 输出: Donald makes a sound
print(duck.fly())    # 输出: Donald is flying
print(duck.swim())   # 输出: Donald is swimming

二、多态:同一操作的不同表现

2.1 多态的概念

多态(Polymorphism)指的是“同一操作作用于不同的对象,可能产生不同的表现形式”。在 Python 中,多态是通过继承和方法重写实现的。即使不同的对象属于不同的类,它们也可以响应相同的方法调用,但可能会有不同的行为。

2.2 Python中的多态

Python 中的多态主要通过方法重写和父类引用指向子类对象的方式实现。我们已经在上面的示例中看到,尽管 DogCat 类都继承了 Animal 类并实现了 speak 方法,但是它们的表现却不同,这就是多态。

2.3 多态示例

我们进一步通过一个例子来展示多态的强大:

# 定义一个函数,接受一个 Animal 类型的对象
def animal_speak(animal):
    print(animal.speak())

# 创建不同类型的 Animal 对象
dog = Dog("Buddy")
cat = Cat("Whiskers")

# 调用函数,展示多态
animal_speak(dog)  # 输出 Buddy barks
animal_speak(cat)  # 输出 Whiskers meows

在这个例子中,animal_speak 函数接受一个 Animal 类型的对象参数,不论传入的是 Dog 还是 Cat 对象,都会调用它们各自实现的 speak 方法。这里的 animal_speak 函数展示了多态的特性:同一个函数调用,不同对象表现出不同的行为。