logo

该视频仅会员有权观看

立即开通课程「Python 入门」权限。

¥
199
/ 年

继承和多态

在面向对象编程中,继承是一种重要的特性,它允许我们定义一个新的类,这个类可以继承一个或多个已有的类的属性和方法,这样就可以实现代码的复用,提高代码的可维护性。

在 Python 中,继承是通过在类定义时在类名后面加上括号指定基类来实现的,如下所示:

class Animal: def __init__(self, name): self.name = name def speak(self): print(f"{self.name} says something") class Dog(Animal): def speak(self): print(f"{self.name} says Woof!") def run(self): print(f"{self.name} is running") class Cat(Animal): def speak(self): print(f"{self.name} says Meow!") dog = Dog("lucy") dog.speak() # 输出: lucy says Woof! cat = Cat("kitty") cat.speak() # 输出: kitty says Meow!

在上面的代码中,我们定义了一个 Animal 类,包含 name 属性和 speak 方法,然后我们定义了 DogCat 类,这两个类继承了 Animal 类,这样 DogCat 类就拥有了 Animal 类的属性和方法,然后我们创建 DogCat 类的实例对象,调用 speak 方法就可以输出不同的声音了,Animal 类 就是基类(父类),DogCat 类是派生类(子类)。

当子类和父类都存在相同的方法时,子类的方法会覆盖父类的方法,在代码运行的时候,总是会调用子类的方法。这样我们就可以根据不同的子类对象调用相同的方法,实现不同的功能。比如上面的 speak 方法,Dog 类和 Cat 类都有 speak 方法,但是实际调用的是子类的 speak 方法。

当我们想要在子类中调用父类的方法时,可以使用 super() 函数,比如下面的例子:

class Animal: def __init__(self, name): self.name = name def speak(self): print(f"{self.name} says something") class Dog(Animal): def speak(self): super().speak() # 调用父类的 speak 方法 print(f"{self.name} says Woof!") dog = Dog("lucy") dog.speak() # 输出: lucy says something lucy says Woof!

在上面的代码中,我们在 Dog 类的 speak 方法中调用了 super().speak() 方法,这样就可以调用父类的 speak 方法,然后再输出 Dog 类的声音。

另外一个子类还可以继承多个父类,这种继承方式称为多重继承,比如下面的例子:

class Animal: def __init__(self, name): self.name = name def speak(self): print(f"{self.name} says something") class Fly: def fly(self): print(f"{self.name} is flying") class Dog(Animal, Fly): # 继承多个父类 def speak(self): super().speak() print(f"{self.name} says Woof!") dog = Dog("lucy") dog.speak() # 输出: lucy says something lucy says Woof! dog.fly() # 输出: lucy is flying

在上面的代码中,Dog 类继承了 Animal 和 Fly 两个父类,这样 Dog 类就拥有了 Animal 和 Fly 两个类的属性和方法,然后我们创建 Dog 类的实例对象,调用 speak 和 fly 方法就可以输出不同的声音和动作了。要继承多个父类时,只需要在类定义时在类名后面的括号中指定多个父类即可,多个父类之间用逗号分隔,这样就可以实现多重继承了。

多态

多态是面向对象编程的一个重要特性,它允许不同的子类对象调用相同的父类方法,但是实际调用的是各自的方法,这样就可以实现不同的功能,提高代码的灵活性和可扩展性。多态不是很好理解,我们通过一个例子来说明多态的概念:

class Animal: def __init__(self, name): self.name = name def speak(self): raise NotImplementedError("Subclass must implement abstract method") class Dog(Animal): def speak(self): return f"{self.name} says Woof!" class Cat(Animal): def speak(self): return f"{self.name} says Meow!" def animal_speak(animal: Animal): print(animal.speak()) dog = Dog("lucy") cat = Cat("kitty") animal_speak(dog) # 输出: lucy says Woof! animal_speak(cat) # 输出: kitty says Meow!

在上面的代码中,我们定义了一个 Animal 类,包含 name 属性和 speak 方法,然后我们定义了 DogCat 类,这两个类继承了 Animal 类,然后我们定义了一个 animal_speak 函数,这个函数接收一个 Animal 类的对象,然后调用 speak 方法,这样就可以实现不同的子类对象调用相同的父类方法,但是实际调用的是各自的方法,这样就实现了多态。

多态的好处是当我们需要增加新的子类时,只需要继承父类并实现相应的方法即可,不需要修改父类的代码,这样就提高了代码的可扩展性和可维护性。

上面我们定义的 animal_speak 函数接收一个 Animal 类的对象,这样就限制了传入的对象必须是 Animal 类的对象,由于 Dog 和 Cat 类都继承了 Animal 类,所以这两个子类对象实际上也是 Animal 类的对象,所以我们可以传入 Dog 和 Cat 类的对象。我们可以使用 isinstance 函数来判断一个对象是否是某个类的实例对象,如下所示:

print(isinstance(dog, Dog)) # 输出: True print(isinstance(cat, Cat)) # 输出: True print(isinstance(dog, Animal)) # 输出: True print(isinstance(cat, Animal)) # 输出: True

面向对象编程的三大特性:封装、继承和多态,这三个特性是面向对象编程的基石,通过这三个特性,我们可以更好地组织代码,提高代码的可维护性和可重用性。