概述
继承在面向对象语言中,是最重要的概念之一,是为了让子类拥有父类的功能,达到代码重用的目的。在有的开发语言中,只能继承一个父类,如JAVA。
python同C++一样,可以继承多个父类
多继承
如上图:
子类可以 继承 多个父类,也就继承了 所有父类 的 属性 和 方法
语法:
class 类名( 父类1 , 父类2 ):
pass
案例1
子类没有实现 __init__() 方法,只会执行 第一个父类的 __init__() 方法,所以 继承第一个父类的属性
代码
Phone类
class Phone:
def __init__(self,cpu,ram,rom):
self.cpu=cpu
self.ram=ram
self.rom=rom
print(str(self.__class__)+" init")
def call(self,number):
print("打电话给:%s"%number)
def sms(self,number,message):
print("发短信给:%s,消息:%s"%(number,message))
IntelligentDevice类
class IntelligentDevice:
def __init__(self):
print(str(self.__class__)+" init")
def install_app(self,app_name):
print("安装 %s"%app_name)
def uninstall_app(self,app_name):
print("卸载 %s"%app_name)
SmartPhone类
class SmartPhone(Phone,IntelligentDevice):
pass
创建 SmartPhone类对象(报错)
iphone=SmartPhone()
执行报错:
TypeError: __init__() missing 3 required positional arguments: 'cpu', 'ram', and 'rom'
原因:因为子类没有实现 __init__() 方法,会执行第一个父类(Phone)的 __init__() 方法,所以需要传入 cpu,ram,rom
正确创建 SmartPhone类对象
iphone=SmartPhone("A11","2G","64G")
print(iphone.cpu)
iphone.call("911")
iphone.sms("110","买了否了")
iphone.install_app("抖音")
小结
继承 所有父类的方法
如果子类没有实现
__init__()方法,会执行第一个父类的__init__()方法。
所以会 继承第一个父类 的实例属性
案例2
子类没有实现 __init__() 方法,只会执行第一个父类的 __init__() 方法,不会执行 第二个父类的 __init__() 方法,所以 不会继承第二个父类的属性
代码
修改 IntelligentDevice 类,在该类定义成员变量 apps(list类型),记录安装的app,代码如下:
class IntelligentDevice:
def __init__(self):
self.apps=[]
print("IntelligentDevice __init__()")
def install_app(self,app_name):
self.apps.append(app_name)
print("安装 %s"%app_name)
def uninstall_app(self,app_name):
self.apps.remove(app_name)
print("卸载 %s"%app_name)
问题
此时,像上例那样定义 SmartPhone 类,并调用就会报错
class SmartPhone(Phone,IntelligentDevice):
pass
调用
iphone=SmartPhone("A11","2G","64G")
iphone.install_app("抖音")
执行结果如下:
AttributeError: 'SmartPhone' object has no attribute 'apps'
因为 SmartPhone 没有继承 IntelligentDevice 类的 apps 属性
没有继承apps属性的原因是:默认调用第一个父类的 __init__() 方法
子类定义__init__()方法
修改SmartPhone类,增加__init__()方法
class SmartPhone(Phone,IntelligentDevice):
def __init__(self):
super().__init__("A11","2G","64G")
调用
iphone=SmartPhone("A11","2G","64G")
iphone.install_app("抖音")
执行结果如下:
AttributeError: 'SmartPhone' object has no attribute 'apps'
解释:
如果子类实现了__init__()方法,就执行自己的__init__()方法。
要继承父类的实例属性,就要执行super().__init__()方法,调用 第一个父类 的__init__()方法
子类调用多个父类的__init__()方法
通过父类的类名调用__init__(self)方法
注意要传入self
class SmartPhone(Phone,IntelligentDevice):
def __init__(self):
Phone.__init__(self,"A11","2G","64G")
IntelligentDevice.__init__(self)
注意:
这种在子类中直接写父类类名的方法,要注意,一旦父类改名了,子类中的父类类名也要及时修改
多继承的问题
- B类继承A类,C类继承A类和B类,这种继承方式 不合理
- C类的
__init__()方法可能会调用A类的__init__()方法,并且也可能调用B类的__init__()方法,B类的__init__()方法可能调用A类的__init__()方法,那么A类的__init__()方法会被执行多次
总结
子类可以 继承 多个父类,也就继承了 所有父类 的 方法,和第一个父类的 属性
多继承中的
__init__()方法如果子类没有实现
__init__()方法,会执行第一个父类的__init__()方法。
所以会 继承第一个父类 的实例属性如果子类实现了
__init__()方法,就执行自己的__init__()方法。
要继承父类的实例属性,就要执行super().__init__()方法,调用 第一个父类 的__init__()方法要继承 所有父类的属性,就要通过 父类名 调用 所有父类的
__init__()

