Python基础语法 第12节课(类 继承)

类的继承 

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():动态设置不存在的属性,设置完该属性,该属性就会存在,可以进行访问.

原文地址:https://www.cnblogs.com/ananmy/p/12934302.html