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(),各自表现出不同的行为——这个特性叫多态,了解名字即可,用多了自然理解。
练习
- 定义
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 猜数字游戏