1、什么是继承
上一节中我们介绍了类与对象的用法。类可以看作是一种程序内的设计图纸,而对象则是基于这个图纸制造出来的实体。这个过程类似于现实中的设计表格和填写表格。
现在假设你是一名设计师,需要迭代一款新产品。你有两个选择:
- 在现有图纸的基础上进行改进,得到新的图纸。
- 从头开始设计全新的图纸。
大多数情况下,你会选择在现有图纸的基础上修修改改。这种方法更高效,因为你可以重用已有的设计,减少重复工作。
在编程中,“继承”就是这个意思。继承允许你从一个已有的类中继承所有的方法和属性,然后在此基础上进行改进,生成一个新的类。这种方式让代码更具复用性,也更易于维护和扩展。
2、继承的语法和实例
2.1单继承
首先,我们介绍继承的语法。假设代码之前已经有创建好的类:
class 类名(父类名):类的内容体
这段代码的意思是在父类(原先创建好的类)的基础上创建一个新的类,新的类继承了父类的所有成员变量和成员方法(属性和行为)。 是不是很简单?让我们来看一个例子。
原先的手机只有4G通话模式,随着科技发展,现在5G通话已经普及。那么我们就在原先手机类的基础上上,运用继承的方法创建一个现在手机的类:
class phone_original:producer='华为'def call_by_4g(self):print('开启4g通话模式')class phone_2024(phone_original):def call_by_5g(self):print('开启5g通话模式')phone=phone_2024()
print(phone.producer)
phone.call_by_5g()
phone.call_by_4g()
创建好后,我们用phone接受phone_2024,并调用call_by_4g和call_by_5g两个成员方法,打印父类属性,输出结果如图:
很显然,新的类继承了父类的成员方法 和成员属性。
由于新的类只继承了一个父类,所以这种继承方式就是单继承。
2.2多继承
多继承顾名思义,就是新的类继承了多个父类。语法相同,让我们再用一个例子实现一下:
如今手机的功能不仅有通话,还可以作为控制智能家居的开关,小区门禁的钥匙,汽车的钥匙,让我们用多继承的方法创建一个新的类,继承父类的成员变量和成员方法:
class phone: # 定义一个名为 phone 的类,表示手机ID = 1001 # 类属性,表示手机的IDproducer = '华为' # 类属性,表示手机的生产厂家def call_by_5g(self): # 定义一个方法,用于5G通话print('开始5g通话') # 输出 '开始5g通话'class house_controller: # 定义一个名为 house_controller 的类,表示家电控制器def open_fridge(self): # 定义一个方法,用于打开冰箱print('打开冰箱') # 输出 '打开冰箱'def open_TV(self): # 定义一个方法,用于打开电视print('打开电视') # 输出 '打开电视'class car_key: # 定义一个名为 car_key 的类,表示车钥匙def open_door(self): # 定义一个方法,用于打开车门print('打开车门') # 输出 '打开车门'class myphone(phone, house_controller, car_key): # 定义一个名为 myphone 的类,继承了 phone, house_controller 和 car_key 类pass # 占位语句,表示类体为空phone = myphone() # 创建 myphone 类的实例对象
phone.call_by_5g() # 调用 myphone 对象的 call_by_5g 方法,输出 '开始5g通话'
phone.open_fridge() # 调用 myphone 对象的 open_fridge 方法,输出 '打开冰箱'
phone.open_TV() # 调用 myphone 对象的 open_TV 方法,输出 '打开电视'
print(f'ID是{phone.ID}') # 输出 'ID是1001'
注释内容已经很详细地解释了代码,代码运行输出如下。
2.3继承的总结
1、语法:
class 类名(父类名):
类的内容体
2、单继承与多继承
(1):单继承是一个类继承另一个类
(2):多继承是一个类继承多个类,按照顺序从左向右依次继承
3、pass关键字:
pass是占位语句,不实现任何功能
3、 复写和使用父类成员
3.1复写父类成员的语法
子类继承父类成员的方法后如果”不满意“,那么可以进行复写。语法是再子类中重新定义同名的属性或方法。
我们还是以4g通话为例。例如,我们现在不满意父类的成员属性和成员方法,可以对其进行复写:
class original_phone:price=3000def call_by_4g(self):print('父类进行4g通话')class phone_2024:price=5000def call_by_4g(self):print('子类进行4g通话')phone=phone_2024()
phone.call_by_4g()
print(f'价格是{phone.price}')
根据打印结果我们可以发现复写后的内容覆盖了原先父类的成员属性和成员方法。
3.2父类成员的使用
一旦复写父类成员,那么类对象调用成员时就会调用复写后的新成员,如果需要使用被复写的父类成员则需要特殊的调用方式:
方式(1)
1、使用成员变量:父类名.成员变量
2、使用成员方法:父类名.成员方法(self)
方式(2)
1、使用成员变量:super( ).成员变量
2、使用成员方法:super( ).成员方法
我们来看这样一段代码:
class phone:ID=Noneproducer='华为'def call_by_5g(self):print('使用5g通话')class myphone(phone):producer='小米'def call_by_5g(self):print('开启单核模式')print('使用5g通话')print('关闭单核,确保性能')phone=myphone()
phone.call_by_5g()
my_phone中复写了父类的成员方法call_by_5g( )。现在想让代码打印父类的厂商,并使用父类的成员方法打印”使用5g通话“。 代码可以这样写:
class phone:ID=Noneproducer='华为'def call_by_5g(self):print('使用5g通话')class myphone(phone):producer='小米'def call_by_5g(self):print('开启单核模式')super().call_by_5g()print('关闭单核,确保性能')print(f'父类厂商是{super().producer}')phone=myphone()
phone.call_by_5g()