Python3学习笔记_类的继承_20200519

22、类的继承

父类 子类
1、继承如何表示?

class 子类名(父类名):
    pass

2、子类可以实现自己独有的方法
重写:子类可以覆盖父类的方法
当子类和父类具有同样的方法或者属性的时候,父类还是会用父类的,子类不再用父类的,而是用自己的

#示例1:

class Phone:
    """手机"""

    def __init__(self, number):
        self.number=number

    def call(self,to_name,record=False):
        print('{}给{}打电话'.format(self.number,to_name))
        if record:
            self.record()

    def record(self):
        print('{}正在录音'.format(self.number))

class SmartPhone(Phone):
    """智能手机"""
    pass

class Iphone:
    pass

normal_phone=Phone('1')
print(normal_phone.record())

smart_phone=SmartPhone('2')
print(smart_phone.record())
print(smart_phone.number)

#示例2:

class SmartPhone(Phone):
    """智能手机"""
    def watch_movie(self,name):
        print('正在看电影{}'.format(name))


normal_phone.watch_movie('红海行动')    #不可以,因为继承是单边的,父类当中不能调用子类方法
smart_phone.watch_movie('红海行动')     #可以,子类可以实现自己独特的方法

#示例3:重写1

class SmartPhone(Phone):
    """智能手机"""
    def __init__(self,number,brand):       #子类可以覆盖父类的方法,当子类和父类具有同样的方法或者属性的时候,父类还是会用父类的,子类不再用父类的,而是用自己的
        self.number=number
        self.brand=brand


normal=Phone('1')
smart=SmartPhone('2')     #这样是不可以的,因为SmartPhone()需要传两个参数

#示例4:重写2

class Iphone(SmartPhone):
    brand='苹果'

    def __init__(self,number):
        self.number=number

    def face_time(self):
        print('{}正在直播'.format(self.number))

    def call(self,to_name,record=False,face=False):
        print('{}给{}打电话'.format(self.number,to_name))
        if record:
            self.record()

        if face:
            self.face_time()

iphone=Iphone('苹果6')
iphone.call('花花',face=True)


smart=SmartPhone('123','huawei')
smart.call('lemon',face=True)         #这样是不可以的,因为这个call()方法,只有Iphone有这个方法,SmartPhone没有的话就找父类Phone,父类有这个方法,但是没有参数:face

#示例5:

iphone=Iphone('123')
iphone.call('lemon',face=True)      #这Iphone的call方法中,调用了record()方法,但是Iphone没有定义这个方法,那就要到父类中找,父类SmartPhone中没有,再到上上一级父类Phone中找,如果最终没找到就会报错

super()函数:超继承,使用父类当中的方法

#示例6:

class Phone:
    """手机"""

    def __init__(self, number):
        self.number=number

    def call(self,to_name,record=False):
        print('{}给{}打电话'.format(self.number,to_name))
        if record:
            self.record()

    def record(self):
        print('{}正在录音'.format(self.number))

class SmartPhone(Phone):
    """智能手机"""
    def __init__(self,number,brand):
        self.number=number
        self.brand=brand

class Iphone(SmartPhone):
    brand='苹果'

    def __init__(self,number):
        self.number=number

    def face_time(self):
        print('{}正在直播'.format(self.number))

    def call(self,to_name,record=False,face=False):
        #print('{}给{}打电话'.format(self.number,to_name))
        #if record:
            #self.record()

        """

        print('{}给{}打电话'.format(self.number,to_name))
        if record:
            self.record()
        这部分代码是从父类--》爷爷类来的,所以可以把这部分代码封装起来,调用爷爷的call方法
        我们可以使用:Phone().call(tp_name,record=False)
        或者是:SmartPhone().call(tp_name,record=False)
        但是SmartPhone()中还要传参数,这样太麻烦,所以引入了super(),super()代表的是父类对象
        super().call(tp_name,record=False)

        """

        super().call(tp_name,record=False)


        if face:
            self.face_time()

#示例7:

class YiFu:
    def __init__(self):
        pass

    def sell(self):
        print('商场正在卖衣服')
        print('卖不出去,打折90%')
        print('还卖不出去,打五折')

class GirlYiFu(YiFu):

    def __init__(self):
        pass

    def sell(self):
        # YiFu().sell()==super().sell()
        super().sell()      #比上面的那些代码复制过来,好多了,万一YiFu()需要传很多参数,就太麻烦了,所以就使用超继承super(),代替父类对象:YiFu()
        print('女装独特的卖衣服的技巧')
        print('你买我的衣服,我还给你钱')

normal=YiFu()
normal.sell()


nvzhuang=GirlYiFu()
nvzhuang.sell()

总结:
1、继承:继承是单边的
2、重写
3、super()

23、类的多重继承:

一个子类可以同时继承多个父类
父类里面的方法子类都可以用

#示例1:

class SmartPhone:
    pass

class Camera:
    pass

class Recorder:
    pass

class Iphone(SmartPhone,Camera,Recorder):
    pass

#属性的动态设置:

class Phone:
    def __init__(self,number):
        self.number=number

phone=Phone('137')

#获取属性:对象.属性

print(phone.number)

#动态获取属性

print(getattr(phone,'number'))

#动态获取属性,可以设置默认值:getattr()
#示例1:

print(phone.brand)               #没有这个属性,所以会报错
print(getattr(phone,'brand'))    #没有这个属性,所以会报错
print(getattr(phone,'brand','苹果'))             #设置默认参数,只是为了不报错,实际还是没有新增brand这个属性
print(getattr(phone,'brand',default='苹果'))     #可以加上default参数,设置默认值,当没有该属性的时候,不会报错

#示例2:

prop_name='brand'
phone.prop_name
phone.brand
print(getattr(phone,prop_name,'苹果'))      #通过传变量的形式取获取属性

#设置属性:setattr()

print(phone.brand)                 #没有这个属性,所以会报错
setattr(phone,'number','155')      #原来的'137'改为了'155'
setattr(phone,'brand','苹果')       #新增了这个属性
print(phone.brand)                 #因为已经新增了这个属性,所以可以得到值,不会报错