Python学习笔记(十九)面向对象 - 继承

Python学习笔记(十九)面向对象 - 继承

一、继承的概念

在这里插入图片描述
在这里插入图片描述

# 继承:子类继承父类的所有方法和属性

# 1. 子类
class A(object):
    def __init__(self):
        self.num = 2
    def info_print(self):
        print(self.num)

# 2. 父类
class B(A):
    pass

result = B()
result.info_print()  # 2

二、单继承

# 1. 师傅类:属性和方法
class Master(object):
    def __init__(self):
        self.kongfu ='[古法煎饼果子配方]'
    def make_cake(self):
        print(f'运用{self.kongfu}制作煎饼果子')

# 2. 徒弟类:继承师傅类
class Prentice(Master):
    pass

# 3. 用徒弟类创建对象,调用实例属性和方法
daiqu = Prentice()

print(daiqu.kongfu)  # [古法煎饼果子配方]

daiqu.make_cake()  # 运用[古法煎饼果子配方]制作煎饼果子

三、多继承

所谓多继承就是一个类同时继承多个父类。

class Master(object):
    def __init__(self):
        self.kongfu ='[古法煎饼果子配方]'
    def make_cake(self):
        print(f'运用{self.kongfu}制作煎饼果子')

class School(object):
    def __init__(self):
        self.kongfu = '[黑马煎饼果子配方]'
    def make_cake(self):
        print(f'运用{self.kongfu}制作煎饼果子')

class Prentice(School,Master):
    pass

daqiu = Prentice()

print(daqiu.kongfu)  # [黑马煎饼果子配方]

daqiu.make_cake()  # 运用[黑马煎饼果子配方]制作煎饼果子

注意:当一个类有多个父类的时候,默认使用第一个父类的同名属性和方法。


四、子类重写父类同名属性和方法

class Master(object):
    def __init__(self):
        self.kongfu ='[古法煎饼果子配方]'
    def make_cake(self):
        print(f'运用{self.kongfu}制作煎饼果子')

class School(object):
    def __init__(self):
        self.kongfu = '[黑马煎饼果子配方]'
    def make_cake(self):
        print(f'运用{self.kongfu}制作煎饼果子')

# 独创配方
class Prentice(School,Master):
    def __init__(self):
        self.kongfu = '[独创煎饼果子配方]'
    def make_cake(self):
        print(f'运用{self.kongfu}制作煎饼果子')

daqiu = Prentice()

print(daqiu.kongfu)  # [独创煎饼果子配方]

daqiu.make_cake()  # 运用[独创煎饼果子配方]制作煎饼果子

结论:如果子类和父类拥有同名属性和方法,那么子类创建对象调用属性和方法的时候,调用的是子类里面的同名属性和方法。

查找某个类的继承关系:

print(Prentice.__mro__)  # 得到类的继承层级关系
# (<class '__main__.Prentice'>, <class '__main__.School'>, <class '__main__.Master'>, <class 'object'>)

五、子类调用父类同名属性和方法

class Master(object):
    def __init__(self):
        self.kongfu ='[古法煎饼果子配方]'
    def make_cake(self):
        print(f'运用{self.kongfu}制作煎饼果子')

class School(object):
    def __init__(self):
        self.kongfu = '[黑马煎饼果子配方]'
    def make_cake(self):
        print(f'运用{self.kongfu}制作煎饼果子')

# 独创配方
class Prentice(School,Master):
    def __init__(self):
        self.kongfu = '[独创煎饼果子配方]'
    def make_cake(self):
        # 如果是先调用了父类的属性和方法,父类属性会覆盖子类属性,故在调用属性前,先调用自己子类的初始化
        self.__init__()
        print(f'运用{self.kongfu}制作煎饼果子')

    # 调用父类方法,但是为保证调用到的也是父类的属性,必须在调用方法前调用父类的初始化
    def make_master_cake(self):
        Master.__init__(self)
        Master.make_cake(self)

    def make_school_cake(self):
        School.__init__(self)
        School.make_cake(self)

daqiu = Prentice()

print(daqiu.kongfu)  # [独创煎饼果子配方]

daqiu.make_cake()  # 运用[独创煎饼果子配方]制作煎饼果子
daqiu.make_master_cake()  # 运用[古法煎饼果子配方]制作煎饼果子
daqiu.make_school_cake()  # 运用[黑马煎饼果子配方]制作煎饼果子

六、多层继承

class Master(object):
    def __init__(self):
        self.kongfu ='[古法煎饼果子配方]'
    def make_cake(self):
        print(f'运用{self.kongfu}制作煎饼果子')
class School(object):
    def __init__(self):
        self.kongfu = '[黑马煎饼果子配方]'
    def make_cake(self):
        print(f'运用{self.kongfu}制作煎饼果子')

# 独创配方
class Prentice(School,Master):
    def __init__(self):
        self.kongfu = '[独创煎饼果子配方]'
    def make_cake(self):
        # 如果是先调用了父类的属性和方法,父类属性会覆盖子类属性,故在调用属性前,先调用自己子类的初始化
        self.__init__()
        print(f'运用{self.kongfu}制作煎饼果子')

    # 调用父类方法,但是为保证调用到的也是父类的属性,必须在调用方法前调用父类的初始化
    def make_master_cake(self):
        Master.__init__(self)
        Master.make_cake(self)

    def make_school_cake(self):
        School.__init__(self)
        School.make_cake(self)

# 徒孙类
class Tusun(Prentice):
    pass

xiaoqiu = Tusun()

print(xiaoqiu.kongfu)  # [独创煎饼果子配方]

xiaoqiu.make_cake()  # 运用[独创煎饼果子配方]制作煎饼果子
xiaoqiu.make_master_cake()  # 运用[古法煎饼果子配方]制作煎饼果子
xiaoqiu.make_school_cake()  # 运用[黑马煎饼果子配方]制作煎饼果子
print(Tusun.__mro__) # (<class '__main__.Tusun'>, <class '__main__.Prentice'>, <class '__main__.School'>, <class '__main__.Master'>, <class 'object'>)

七、super()调用父类方法

之前的函数类名.父类方法也可以调用父类方法,代码如下:

class Master(object):
    def __init__(self):
        self.kongfu ='[古法煎饼果子配方]'
    def make_cake(self):
        print(f'运用{self.kongfu}制作煎饼果子')

class School(object):
    def __init__(self):
        self.kongfu = '[黑马煎饼果子配方]'
    def make_cake(self):
        print(f'运用{self.kongfu}制作煎饼果子')

# 独创配方
class Prentice(School,Master):
    def __init__(self):
        self.kongfu = '[独创煎饼果子配方]'
    def make_cake(self):
        # 如果是先调用了父类的属性和方法,父类属性会覆盖子类属性,故在调用属性前,先调用自己子类的初始化
        self.__init__()
        print(f'运用{self.kongfu}制作煎饼果子')

    # 需求:一次性调用父类Master School 的方法
    def make_old_cake(self):
        # 方法一: 如果定义的类名修改,这里的类名也要修改,麻烦:代码量太庞大,冗余
        School.__init__(self)
        School.make_cake(self)
        Master.__init__(self)
        Master.make_cake(self)

daqiu = Prentice()

daqiu.make_old_cake()  

在这里插入图片描述
用super()调用父类方法:

class Master(object):
    def __init__(self):
        self.kongfu ='[古法煎饼果子配方]'
    def make_cake(self):
        print(f'运用{self.kongfu}制作煎饼果子')

class School(Master):
    def __init__(self):
        self.kongfu = '[黑马煎饼果子配方]'
    def make_cake(self):
        print(f'运用{self.kongfu}制作煎饼果子')
        
        super(School, self).__init__()
        super(School, self).make_cake()

# 独创配方
class Prentice(School):
    def __init__(self):
        self.kongfu = '[独创煎饼果子配方]'
    def make_cake(self):
        # 如果是先调用了父类的属性和方法,父类属性会覆盖子类属性,故在调用属性前,先调用自己子类的初始化
        self.__init__()
        print(f'运用{self.kongfu}制作煎饼果子')

    # 需求:一次性调用父类Master School 的方法
    def make_old_cake(self):

        # 方法二:super()
        # 方法2.1 super(当前类名,self).函数()
        super(Prentice,self).__init__()
        super(Prentice,self).make_cake()


daqiu = Prentice()

daqiu.make_old_cake()

在这里插入图片描述

class Master(object):
    def __init__(self):
        self.kongfu ='[古法煎饼果子配方]'
    def make_cake(self):
        print(f'运用{self.kongfu}制作煎饼果子')

class School(Master):
    def __init__(self):
        self.kongfu = '[黑马煎饼果子配方]'
    def make_cake(self):
        print(f'运用{self.kongfu}制作煎饼果子')
        # super(School, self).__init__()
        # super(School, self).make_cake()
        super().__init__()
        super().make_cake()


# 独创配方
class Prentice(School):
    def __init__(self):
        self.kongfu = '[独创煎饼果子配方]'
    def make_cake(self):
        # 如果是先调用了父类的属性和方法,父类属性会覆盖子类属性,故在调用属性前,先调用自己子类的初始化
        self.__init__()
        print(f'运用{self.kongfu}制作煎饼果子')

    # 需求:一次性调用父类Master School 的方法
    def make_old_cake(self):
        # # 方法一: 如果定义的类名修改,这里的类名也要修改,麻烦:代码量太庞大,冗余
        # School.__init__(self)
        # School.make_cake(self)
        # Master.__init__(self)
        # Master.make_cake(self)

        # 方法二:super()
        
        # # 方法2.1 super(当前类名,self).函数()
        # super(Prentice,self).__init__()
        # super(Prentice,self).make_cake()
        
        # 方法2.2 无参数super().函数()
        super().__init__()
        super().make_cake()

daqiu = Prentice()

daqiu.make_old_cake()

在这里插入图片描述
在这里插入图片描述


八、私有属性和私有方法

8.1 定义私有属性和方法

在Python中,可以为实例属性和方法设置私有权限,即设置某个实例属性或者实例方法不继承给子类。

设置私有权限的方法:在属性名 或 方法名 前加两个下划线__

class Master(object):
    def __init__(self):
        self.kongfu ='[古法煎饼果子配方]'
    def make_cake(self):
        print(f'运用{self.kongfu}制作煎饼果子')

class School(object):
    def __init__(self):
        self.kongfu = '[黑马煎饼果子配方]'
    def make_cake(self):
        print(f'运用{self.kongfu}制作煎饼果子')

# 独创配方
class Prentice(School,Master):
    def __init__(self):
        self.kongfu = '[独创煎饼果子配方]'
        # 私有属性: 不能继承给子类
        self.__money = 2000000

    def make_cake(self):
        # 如果是先调用了父类的属性和方法,父类属性会覆盖子类属性,故在调用属性前,先调用自己子类的初始化
        self.__init__()
        print(f'运用{self.kongfu}制作煎饼果子')

    # 定义私有方法:不能继承给子类
    def __info_print(self):
        print('这是私有方法')

    def make_master_cake(self):
        Master.__init__(self)
        Master.make_cake(self)

    def make_school_cake(self):
        School.__init__(self)
        School.make_cake(self)

class Tusun(Prentice):
    pass

xiaoqiu = Tusun()
print(xiaoqiu.money)  # money 是 Prentice的私有属性,故子类没有这个属性
print(xiaoqiu.info_print) # info_print() 是Prentice的私有方法,故子类没有这个方法

8.2 获取和修改私有属性

在Python中,一般定义函数get__xx用来获取私有属性,定义set__xx用来修改私有属性值。

class Master(object):
    def __init__(self):
        self.kongfu ='[古法煎饼果子配方]'
    def make_cake(self):
        print(f'运用{self.kongfu}制作煎饼果子')

class School(object):
    def __init__(self):
        self.kongfu = '[黑马煎饼果子配方]'
    def make_cake(self):
        print(f'运用{self.kongfu}制作煎饼果子')

# 独创配方
class Prentice(School,Master):
    def __init__(self):
        self.kongfu = '[独创煎饼果子配方]'
        # 私有属性: 不能继承给子类
        self.__money = 2000000

    # 获取私有属性的值 get__xx()
    def get_money(self):
        return self.__money

    # 修改私有属性的值 set__xx()
    def set_money(self):
        self.__money = 50000

    def make_cake(self):
        # 如果是先调用了父类的属性和方法,父类属性会覆盖子类属性,故在调用属性前,先调用自己子类的初始化
        self.__init__()
        print(f'运用{self.kongfu}制作煎饼果子')

    # 定义私有方法:不能继承给子类
    def __info_print(self):
        print('这是私有方法')

    def make_master_cake(self):
        Master.__init__(self)
        Master.make_cake(self)

    def make_school_cake(self):
        School.__init__(self)
        School.make_cake(self)

class Tusun(Prentice):
    pass

xiaoqiu = Tusun()
print(xiaoqiu.get_money())  # 2000000
xiaoqiu.set_money()  # 修改
print(xiaoqiu.get_money())  # 50000

九、总结

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值