目录

第十四章:继承与多态

本章目标

完成本章学习后,你将能够:

继承基础

单继承

class Animal:
    """动物基类"""
 
    def __init__(self, name):
        self.name = name
 
    def speak(self):
        raise NotImplementedError("子类必须实现此方法")
 
    def info(self):
        return f"{self.name} is an animal"
 
class Dog(Animal):  # Dog继承Animal
    """狗类"""
 
    def __init__(self, name, breed):
        super().__init__(name)  # 调用父类构造方法
        self.breed = breed
 
    def speak(self):  # 方法重写(覆盖)
        return f"{self.name} says woof!"
 
    def fetch(self):  # 子类特有方法
        return f"{self.name} is fetching"
 
class Cat(Animal):
    """猫类"""
 
    def speak(self):
        return f"{self.name} says meow!"
 
# 使用
dog = Dog("Buddy", "Golden Retriever")
cat = Cat("Whiskers")
 
print(dog.speak())   # Buddy says woof!
print(cat.speak())   # Whiskers says meow!
print(dog.fetch())   # Buddy is fetching
print(dog.info())    # Buddy is an animal(继承的方法)

super()函数

class A:
    def __init__(self):
        print("A.__init__")
        self.a = "A"
 
class B(A):
    def __init__(self):
        print("B.__init__")
        super().__init__()  # 调用A的__init__
        self.b = "B"
 
class C(B):
    def __init__(self):
        print("C.__init__")
        super().__init__()  # 调用B的__init__(实际是调用MRO中的下一个)
        self.c = "C"
 
# MRO(方法解析顺序)
print(C.__mro__)  # (<class 'C'>, <class 'B'>, <class 'A'>, <class 'object'>)

多继承

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):  # 多继承
    def __init__(self, name):
        super().__init__(name)
 
    def speak(self):
        return f"{self.name} says quack!"
 
# 使用
duck = Duck("Donald")
print(duck.speak())  # Donald says quack!
print(duck.fly())    # Donald is flying
print(duck.swim())   # Donald is swimming

MRO和菱形继承

class A:
    def method(self):
        print("A")
 
class B(A):
    def method(self):
        print("B")
        super().method()
 
class C(A):
    def method(self):
        print("C")
        super().method()
 
class D(B, C):  # 菱形继承
    def method(self):
        print("D")
        super().method()
 
# MRO: D -> B -> C -> A -> object
print(D.__mro__)
 
d = D()
d.method()
# 输出:
# D
# B
# C
# A

多态与鸭子类型

多态

class Animal:
    def speak(self):
        pass
 
class Dog(Animal):
    def speak(self):
        return "Woof!"
 
class Cat(Animal):
    def speak(self):
        return "Meow!"
 
def animal_concert(animals):
    """多态:不同类型的对象以相同接口处理"""
    for animal in animals:
        print(animal.speak())
 
# 同一接口,不同行为
animals = [Dog(), Cat(), Dog()]
animal_concert(animals)

鸭子类型

class Duck:
    def swim(self):
        print("Duck swimming")
    def fly(self):
        print("Duck flying")
 
class Swan:
    def swim(self):
        print("Swan swimming")
    def fly(self):
        print("Swan flying")
 
class Goose:
    def swim(self):
        print("Goose swimming")
    def fly(self):
        print("Goose flying")
 
def water_bird_demo(bird):
    """
    鸭子类型:不关注对象类型,只关注是否有需要的方法
    "如果它走起来像鸭子,叫起来像鸭子,那它就是鸭子"
    """
    bird.swim()
    bird.fly()
 
# 不同类型的对象都可以传入
water_bird_demo(Duck())
water_bird_demo(Swan())
water_bird_demo(Goose())

抽象基类

from abc import ABC, abstractmethod
 
class Shape(ABC):  # 抽象基类
    @abstractmethod
    def area(self):
        """子类必须实现此方法"""
        pass
 
    @abstractmethod
    def perimeter(self):
        pass
 
    def info(self):  # 可以有具体方法
        return f"Area: {self.area()}, Perimeter: {self.perimeter()}"
 
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)
 
# shape = Shape()  # TypeError: 不能实例化抽象类
rect = Rectangle(5, 3)
print(rect.info())

本章小结

本章我们学习了:

下一章:第十五章:模块与包