类的继承
1.子类 父类的概念
2.子类通过继承可以获得父类的方法和属性,作用就是提高代码的效率和复用率
注:私有属性不能继承
3.继承的表示方法:
class 子类名(父类名):
pass
class Phone: def __init__(self, number): self.number = number def call(self, toWho, record=False): # 默认不录音 """打电话""" print('本机号:{}正在给{}打电话'.format(self.number, toWho)) if record: self.record() def record(self): print('打电话的时候,正在录音') #智能手机 class smartPhone(Phone):#子类smartPhone继承父类Phone的方法和属性 pass class IPhone(): pass #初始化一个普通手机 normal_phone = Phone('15866668888') print(normal_phone.call('polo')) print(normal_phone.number) #初始化一个智能手机huawei huawei = smartPhone('13988886666')#smartPhone继承了父类Phone的__init__,这里需要传入number的参数 print(huawei.call('roby')) print(huawei.number)
'''
本机号:15866668888正在给polo打电话
None
15866668888
本机号:13988886666正在给roby打电话
None
13988886666
'''
即:只要是继承了父类,子类就可以调用父类的所有属性和方法
4.子类 自己定义了方法------父类不能调用子类的方法,因为继承是单向的,子类继承父类
举例:父类不能调用子类的方法
class Phone: def __init__(self, number): self.number = number def call(self, toWho, record=False): # 默认不录音 """打电话""" print('本机号:{}正在给{}打电话'.format(self.number, toWho)) if record: self.record() def record(self): print('打电话的时候,正在录音') #智能手机 class smartPhone(Phone): def watch_moive(self,name): print('正在看{}电影') class IPhone(): pass #父类不能调用子类的方法 normal_Phone = Phone('18855552222') print(normal_Phone.watch_moive('流浪地球')) ''' AttributeError: 'Phone' object has no attribute 'watch_moive' '''
5.子类可以自己定义__init__
♥当子类 和 父类 具有同样的方法名 或者属性的时候,父类还是用父类的,子类不再使用父类的,而是使用自己的。
即只要子类定义了跟父类同名的方法或属性,就必须用自己的,不能用父类的。-----子类覆盖父类的方法,即重写。
举例:子类重写父类的方法,调用必须用自己的
class Phone: def __init__(self, number): self.number = number def call(self, toWho, record=False): # 默认不录音 """打电话""" print('本机号:{}正在给{}打电话'.format(self.number, toWho)) if record: self.record() def record(self): print('打电话的时候,正在录音') #智能手机 class smartPhone(Phone): def __init__(self,name,brand): self.name = name self.brand = brand def watch_moive(self,moive_name): print('用{}手机正在看电影:{}'.format(self.name,moive_name)) class IPhone(): pass #实例化一个智能手机对象oppo oppo = smartPhone('oppo','30')#这里传入的参数必须是2个,子类重写父类的方法,子类调用必须用自己的 print(oppo.name) print(oppo.brand) print(oppo.watch_moive('《流浪地球》')) ''' oppo 30 用oppo手机正在看电影:《流浪地球》 None '''
6.两层继承,子类没有的方法,可以去父类的父类找,即可以调用上上。。级的方法。
class Phone: def __init__(self, number): self.number = number def call(self, toWho, record=False): # 默认不录音 """打电话""" print('本机号:{}正在给{}打电话'.format(self.number, toWho)) if record: self.record() def record(self): print('打电话的时候,正在录音') #智能手机 class SmartPhone(Phone): def __init__(self,name,brand): self.name = name self.brand = brand def watch_moive(self,moive_name): print('用{}手机正在看电影:{}'.format(self.name,moive_name)) class IPhone(SmartPhone): def __init__(self,number): self.number = number self.brand = '苹果8' def face_time(self): '''直播''' print('{}正在直播'.format(self.number)) def call(self, toWho, record = False,face = False): '''打电话既可以录音 也可以facetime''' print('{}正在给{}打电话'.format(self.number,toWho)) if record: self.record() #IPhone这个类里面没有record()方法,就往父类找,父类没有,就往父类的父类去找 if face: self.face_time() #实例化一个对象iPhone iPhone = IPhone('19977776666') print(iPhone.call('Lucy',True)) ''' 19977776666正在给Lucy打电话 打电话的时候,正在录音 None '''
7.super()函数-超继承,不需要传参数
使用父类当中的方法 ,简化父类方法调用的过程。
♥super()函数只能是调用父类的方法 (不能越级调用父类的父类)
class SmartPhone(): def __init__(self,name,brand): self.name = name self.brand = brand def watch_moive(self,moive_name): print('用{}手机正在看电影:{}'.format(self.name,moive_name)) class IPhone(SmartPhone): #使用super()函数调用父类的__init__ def __init__(self,number,brand): super().__init__(number,'苹果')#这里不用self参数 # 使用了super()函数就不需要下面的代码了 # self.number = number # self.brand = '苹果8' #实例化一个对象iphone iphone = IPhone(8,'苹果') print(iphone.brand)#苹果
super()就表示想用父类的所有方法(类方法、实例方法、静态方法),代表的就是一个对象或者类
class Phone: def __init__(self,number,brand): self.number = number self.brand = brand def call(self,to_who,record = False): print('手机号:{}正在给{}打电话'.format(self.number,to_who)) if record: print('打电话的时候正在录音') class SmartPhone(Phone): def __init__(self,number,brand): super().__init__(number,brand) def call(self,to_who,record = False,face_time = False):#子类的call方法在继承父类的方法的基础上,有face_time-->即用super()继承父类的call,子类自己独有的功能,再继续添加 super().call(to_who,record = False) if face_time: print('视频通话') #实例化 Iphnoe = SmartPhone('18899996666','apple') print(Iphnoe.call('polo',True,True)) ''' 手机号:18899996666正在给polo打电话 视频通话 None '''
下面例子的super() ==SmartPhone(‘’,‘’,‘’。。。。)
class Phone: def call(self,towho): pass class SmartPhone(Phone): def call(self,towho,face = False): pass class IPhone(SmartPhone): def call(self, towho, face=False): super().call(towho) #只能调用父类的,不能越级调用 print('正在给{}打电话'.format(towho)) #实例化一个对象 iPhone = IPhone() print(iPhone.call('tudou',True))
总结:
1.super():子类使用super()函数,继承父类的方法,如果父类的方法里是传参数的,子类的方法也要正常传参数(上例子的橙色底表示)
2.super()函数可以简化代码,不用也是可以的。
3.继承父类,父类的方法就可以用。如果子类定义了(重写),就可以不用父类的方法
类的多重继承
1.多重继承的含义:一个子类可以同时继承多个父类,这多个父类的方法和属性,都可以访问
举例:
class SmartPhone: pass class Camera: pass class Recorder: pass #Iphone这个子类同时继承上面3个父类 class Iphone(SmartPhone,Camera,Recorder): pass
属性的动态设置---扩展知识
之前学的的获取属性的方法是:通过对象.属性去获取属性
class Iphone: def __init__(self,number): self.number = number #实例化一个对象iphone iphone = Iphone('888') print(iphone.number)#888
1.那么如何动态获取属性?------getattr()的内置函数: 用于动态返回一个对象属性值
①getattr()的源码表示如下
def getattr(object,name,default = None):
- object -- 对象。
- name -- 字符串,对象属性。
- default -- 默认返回值,如果不提供该参数,在没有对应属性时,将触发 AttributeError。
❤ getattr() 动态获取对象属性
class Iphone: def __init__(self,number): self.number = number #实例化一个对象iphone iphone = Iphone('888') print(iphone.number)#888 #动态获取该对象的属性 print(getattr(iphone,'number')) #888,这里的number是字符串
❤ getattr()动态设置不存在的属性
getattr(iphone,'brand','苹果'),iphone对象并没有brand这个属性,返回默认给的‘苹果’,这个brand是不存在的。
class Iphone: def __init__(self,number): self.number = number #实例化一个对象iphone iphone = Iphone('888') print(iphone.number)#888 #动态获取该对象的属性 print(getattr(iphone,'number')) #888,这里的number是字符串 # 动态设置不存在的属性 print(getattr(iphone,'brand','苹果'))#苹果
print(iphone.brand)就会报错。attributeError,因为没有brand这个属性
❤ 加default参数,设置默认值,当没有该属性时,不会报错,而是返回默认值??????没明白,运行报错了
❤动态属性赋值给变量 可以将属性定义为变量传入----------属性名 == 变量
class Iphone: def __init__(self,number): self.number = number #实例化一个对象iphone iphone = Iphone('888') print(iphone.number)#888 #动态获取该对象的属性 print(getattr(iphone,'number')) #888,这里的number是字符串 #属性赋值给变量,通过变量获取属性 prop_name = 'brand' #这里可以尝试用input函数,输入字符串 print(getattr(iphone,prop_name,'苹果'))
2.如何设置属性?------setattr()
设置属性后,这个属性就存在了,可以访问
class Iphone: def __init__(self,number): self.number = number #实例化一个对象iphone iphone = Iphone('888') print(iphone.number)#888 #动态设置属性 setattr(iphone,'number','999') #------→这里就等价于iphone.numbe = '999',但是这个方法是不能用变量的 print(iphone.number)#999 #设置不存在的属性 setattr(iphone,'color','white')
#访问设置的属性 print(iphone.color)#white
总结:setattr() getattr()
getattr():①动态获取属性(已经存在的),②动态设置时,不存在的属性,返回默认值
setattr():动态设置不存在的属性,设置完该属性,该属性就会存在,可以进行访问.