继承和多态
继承¶
在面向对象编程中,继承是一个重要的特性,他允许我们定义一个新的类,这个类可以继承一个或者多个已有的类的属性和方法,这样就可以实现代码的复用,提高代码的可维护性.
在 Python 中,继承是通过在类定义时在类名后面加上括号指定基类来实现的.如下所示:
class Animal():
def __init__(self,name,age) -> None:
self.name = name
self.age = age
def speak(self):
print(f"{self.name} says something")
class Dog(Animal):
def speak(self):
print(f"Dog: {self.name} is woof! {self.name} is {self.age} year old!")
def run(self):
print(f"{self.name} is running!")
class Cat(Animal):
def speak(self):
print(f"Cat: {self.name} is Meow! {self.name} is {self.age} year old!")
my_dog = Dog('Yuki',3)
my_dog.speak()
my_cat = Cat('Tom',1)
my_cat.speak()
在以上代码中,我们定义了Animal类,类中包含了name和age 两个属性和包含一个 speak方法,后面我们定义了Dog 和 Cat 两个类,这两个类继承了 Animal类,所以Dog 和 Cat 两个类就拥有了 Animal 类 的属性和方法. 然后我们创建Dog 和 Cat 类的实例对象. 调用 speak()方法就可以输出不同的声音了,Animal 是基类(父类),Dog 和 Cat 是派生类(子类)
当子类和父类都存在相同的方法时,子类的方法会覆盖父类的方法.在代码运行的时候,总是会调用子类的方法.这样我们就可以根据不同子类对象调用相同方法,实现不同的功能.比如上面的 speak 方法.Dog 类和 Cat 类都有 speak 方法,但是实际调用的是子类的 speak 方法.
当我们想要在子类中调用父类的方法时,可以使用super()函数,比如下面的例子:
class Cat(Animal):
def speak(self):
super().speak() # 调用父类的speak方法
print(f"Cat: {self.name} is Meow! {self.name} is {self.age} year old!")
另外子类还可以继承多个父类,这种继承方式称为多重继承,比如下面的例子:
class Animal():
def __init__(self,name,age) -> None:
self.name = name
self.age = age
def speak(self):
print(f"{self.name} says something")
class Fly():
def fly(self):
print(f"{self.name} is flying!")
class Cat(Animal,Fly): # 调用多个父类
def speak(self):
super().speak()
print(f"Cat: {self.name} is Meow! {self.name} is {self.age} year old!")
my_cat = Cat('Tom',1)
my_cat.speak()
my_cat.fly()
多态¶
多态是面向对象编程的一个重要特性,他允许不同的子类对象调用不同的父类方法,但实际调用的是各自的方法.这样就可以实现不同的功能,提供代码的灵活性和扩展性.
class Animal():
def __init__(self,name,age) -> None:
self.name = name
self.age = age
def speak(self):
print(f"{self.name} says something")
class Dog(Animal):
def speak(self):
print(f"Dog: {self.name} is woof! {self.name} is {self.age} year old!")
def run(self):
print(f"{self.name} is running!")
class Cat(Animal):
def speak(self):
print(f"Cat: {self.name} is Meow! {self.name} is {self.age} year old!")
def animal_speak(animal: Animal):
animal.speak()
dog = Dog('Tom',1)
cat = Cat('lili',2)
animal_speak(dog) # 输出: Dog: Tom is woof! Tom is 1 year old!
animal_speak(cat) # 输出: Cat: lili is Meow! lili is 2 year old!
在上面的代码中,我们定义了一个 Animal 的类,这个类包含 name 和 age 属性和 speak 方法.然后我们又定义了两个类一个是Dog 类,一个是Cat 类.这两个类继承了 Animal 类,然后我们定义了一个 animal_speak() 函数,这个函数接收一个Animal 类的对象,然后调用speak方法.这样子就可以实现不同的子类对象调用相同的父类方法,但是实际调用的是各自的方法,这样就实现了多态
多态的好处? 当我们增加新的子类时,只需要继承父类并实现相应的方法即可,不需要修改父类的代码,这样就提高了代码的可扩展性和维护性.
上面我们定义了animal_speak 函数接受了一个Animal 类对象,这样就限制了传入的对象必须是Animal类的对象,由于 Dog 和 Cat 类继承了 Animal 类,这两个子类的对象实际也是Animal 类的对象,所以我们可以传入 Dog 和 Cat 类的对象.我们可以使用 isinstance 函数来判断一个对象是否是某个类的实例对象
print(isinstance(dog, Dog))
print(isinstance(cat, Cat))
print(isinstance(dog, Animal))
print(isinstance(cat, Animal))