跳到主要内容

9.2 继承

什么是继承

继承让一个类拥有另一个类的全部能力,然后在此基础上扩展。用来解决"几个类大部分代码相同"的重复问题。

比如猫和狗:都有名字、都会吃饭、都会睡觉,只是叫声不同。把共同部分提取成"动物"类,猫和狗继承它:

class Animal: # 父类(基类)
def __init__(self, name):
self.name = name

def eat(self):
print(f"{self.name} 在吃饭")

def sleep(self):
print(f"{self.name} 在睡觉")


class Cat(Animal): # Cat 继承 Animal,括号里写父类名
def speak(self):
print(f"{self.name}:喵喵~")


class Dog(Animal):
def speak(self):
print(f"{self.name}:汪汪!")


cat = Cat("咪咪")
cat.eat() # 咪咪 在吃饭 ← eat 是从 Animal 继承来的,没写也能用
cat.speak() # 咪咪:喵喵~ ← 自己新增的方法

dog = Dog("旺财")
dog.sleep() # 旺财 在睡觉
dog.speak() # 旺财:汪汪!
  • class Cat(Animal): —— Cat 是子类,Animal 是父类
  • 子类自动拥有父类的所有属性和方法
  • 子类可以新增自己的方法

方法重写:子类覆盖父类的行为

子类定义和父类同名的方法,就会覆盖父类版本:

class Animal:
def speak(self):
print("动物在叫")

class Cat(Animal):
def speak(self): # 重写父类的 speak
print("喵喵~")

Cat().speak() # 喵喵~ (执行的是子类版本)

super():调用父类的方法

子类想在父类的基础上补充(而不是完全替换)时,用 super() 调用父类版本。最常见于 __init__

class Animal:
def __init__(self, name):
self.name = name


class Dog(Animal):
def __init__(self, name, breed):
super().__init__(name) # 先让父类完成 name 的初始化
self.breed = breed # 再补充自己特有的属性


dog = Dog("旺财", "柴犬")
print(dog.name) # 旺财
print(dog.breed) # 柴犬

⚠️ 子类一旦定义了自己的 __init__,父类的就不再自动执行,所以需要 super().__init__(...) 手动调用,否则 self.name 就不存在了。

综合例子:员工系统

class Employee:
def __init__(self, name, salary):
self.name = name
self.salary = salary

def work(self):
print(f"{self.name} 在工作")

def get_pay(self):
return self.salary


class Programmer(Employee):
def work(self): # 重写
print(f"{self.name} 在写代码")


class Manager(Employee):
def __init__(self, name, salary, bonus):
super().__init__(name, salary)
self.bonus = bonus

def get_pay(self): # 重写:经理多拿奖金
return self.salary + self.bonus


staff = [
Programmer("小明", 15000),
Manager("老王", 20000, 5000),
]

for s in staff:
s.work()
print(f"{s.name} 月收入:{s.get_pay()} 元")

注意最后的循环:不管是程序员还是经理,都调用同样的 work()get_pay(),各自表现出不同的行为——这个特性叫多态,了解名字即可,用多了自然理解。

练习

  1. 定义 Shape 类(有 area() 方法,返回 0);再定义 Circle(属性半径)和 Rectangle(属性长、宽)继承它并重写 area()。创建对象验证面积计算。
点击查看答案
import math

class Shape:
def area(self):
return 0

class Circle(Shape):
def __init__(self, r):
self.r = r

def area(self):
return math.pi * self.r ** 2

class Rectangle(Shape):
def __init__(self, w, h):
self.w = w
self.h = h

def area(self):
return self.w * self.h

print(f"{Circle(2).area():.2f}") # 12.57
print(Rectangle(3, 4).area()) # 12

本章小结

  • class 子类(父类): 子类自动获得父类的一切
  • 同名方法覆盖父类(重写)
  • 子类 __init__ 里用 super().__init__(...) 调父类初始化

基础知识全部学完!🎉 接下来用三个实战项目检验成果:10.1 猜数字游戏