11.1 继承语法与子类创建
继承是面向对象编程的三大特性之一,它允许我们基于已有的类创建新类。新类会自动获得父类的所有属性和方法,这就是"站在巨人的肩膀上"写代码!
在Python中,创建子类的语法非常简单:在定义类时,在括号中指定父类名称即可。
python
# 定义父类
class Animal:
def __init__(self, name):
self.name = name # 父类的实例属性
def speak(self):
print(f"{self.name} 发出声音") # 父类的方法
# 定义子类,继承自Animal
class Dog(Animal): # Dog类继承了Animal类
def __init__(self, name, breed):
super().__init__(name) # 调用父类的构造方法
self.breed = breed # 子类特有的属性
# 创建子类实例
my_dog = Dog("旺财", "金毛")
print(my_dog.name) # 可以访问父类的属性
print(my_dog.breed) # 可以访问子类的属性
my_dog.speak() # 可以调用父类的方法继承的好处显而易见:避免重复代码,提高代码复用性。子类可以拥有父类的所有功能,同时还能添加自己的特色功能。
11.2 方法重写基础
有时候父类的方法不能完全满足子类的需求,这时候就需要方法重写(也叫方法覆盖)。子类可以定义与父类同名的方法,这样在调用时就会优先使用子类的方法。
python
# 父类
class Animal:
def __init__(self, name):
self.name = name
def speak(self):
print(f"{self.name} 发出声音")
# 子类重写父类的speak方法
class Cat(Animal):
def __init__(self, name, color):
super().__init__(name)
self.color = color
# 重写父类的speak方法
def speak(self):
print(f"{self.name} 喵喵叫") # 子类特有的实现
# 子类也可以选择不重写
class Bird(Animal):
pass # Bird类直接使用父类的speak方法
# 测试方法重写
my_cat = Cat("咪咪", "白色")
my_bird = Bird("小黄")
my_cat.speak() # 输出: 咪咪 喵喵叫 (调用子类重写的方法)
my_bird.speak() # 输出: 小黄 发出声音 (调用父类的方法)方法重写让我们能够为不同的子类提供特定的行为实现,这是实现多态的基础。
11.3 super() 函数简单使用
super() 函数是处理继承关系的利器,它返回一个代理对象,让你能够调用父类的方法。最常见的用途是在子类的 __init__ 方法中调用父类的构造方法。
python
# 父类
class Vehicle:
def __init__(self, brand, model):
self.brand = brand
self.model = model
self.is_running = False
def start(self):
self.is_running = True
print(f"{self.brand} {self.model} 启动了")
def stop(self):
self.is_running = False
print(f"{self.brand} {self.model} 停止了")
# 子类使用super()调用父类方法
class Car(Vehicle):
def __init__(self, brand, model, doors):
super().__init__(brand, model) # 调用父类构造方法
self.doors = doors
def start(self):
super().start() # 先调用父类的start方法
print("汽车启动,准备出发!") # 再执行子类特有的逻辑
def honk(self): # 子类特有的方法
if self.is_running:
print("滴滴!")
else:
print("汽车未启动,无法按喇叭")
# 使用示例
my_car = Car("丰田", "卡罗拉", 4)
my_car.start() # 会先调用父类start,再执行子类的额外逻辑
my_car.honk()
my_car.stop()使用 super() 的好处是代码更加灵活,如果父类名称发生变化,子类代码不需要修改。
提示
需要留意的是,在多重继承(一个子类同时继承多个父类)时,super() 会按照 MRO(方法解析顺序)去查找下一个方法,并不一定是直接父类。初学者掌握单继承中的用法即可,深入学习继承体系时可再研究 MRO。
11.4 多态的简单理解
多态是指同一个接口可以有不同的实现方式。在Python中,由于是动态类型语言,多态体现得更加自然——我们不需要关心对象的具体类型,只要它有相应的方法就可以。
python
# 定义多个具有相同接口的类
class Dog:
def speak(self):
return "汪汪汪"
class Cat:
def speak(self):
return "喵喵喵"
class Duck:
def speak(self):
return "嘎嘎嘎"
# 多态函数:接受任何有speak方法的对象
def animal_sound(animal):
# 不关心animal具体是什么类型,只要有speak方法就行
print(animal.speak())
# 创建不同类型的对象
animals = [Dog(), Cat(), Duck()]
# 对所有动物调用相同的方法,但得到不同的结果
for animal in animals:
animal_sound(animal) # 多态的体现
# 另一个多态示例:计算不同形状的面积
class Rectangle:
def __init__(self, width, height):
self.width = width
self.height = height
def area(self):
return self.width * self.height
class Circle:
def __init__(self, radius):
self.radius = radius
def area(self):
return 3.14159 * self.radius ** 2
# 多态函数计算面积
def calculate_area(shape):
return shape.area() # 不关心shape是矩形还是圆形
# 使用多态
shapes = [Rectangle(5, 3), Circle(4)]
for shape in shapes:
print(f"面积: {calculate_area(shape)}")多态让我们的代码更加通用和灵活,这也是面向对象编程的魅力所在。通过多态,我们可以编写出能够处理多种不同类型对象的通用函数。