zoukankan      html  css  js  c++  java
  • 学习python的day13之面向对象-继承

    面向对象-继承

    1.体验继承

    python面向对象的继承指多个类之间的从属关系,即子类默认及继承父类的所有属性和方法,具体如下:

    #父类
    class A(object):
        def __init__(self):
            self.num = 1
        def info_print(self):
            print(self.num)
    
    #子类
    class B(A):
        pass
    
    redult = B()
    redult.info_print()
    
    '''
    输出:
    1
    '''

    在python中,所有类默认继承object类,object类是顶级类或基类,其他字类叫派生类

    2.单继承

    故事主线:一个煎饼果子老师傅,在煎饼果子界摸爬滚打多年,研发了一套精湛的煎饼果子技术。师傅要把这套技术传授给徒弟。

    分析:要有两个类(师傅类、徒弟类),徒弟类继承师傅类

    class Master(object):
        def __init__(self):
            self.mifang = '独门绝技'
        def make_cake(self):
            print(f'使用{self.mifang}制作煎饼果子')
    class Prentice(Master):
        pass
    tuer = Prentice()
    tuer.make_cake()
    '''
    输出:
    使用独门绝技制作煎饼果子
    '''

    3.多继承

    故事推进:tuer继承师傅的独门绝技后,还想去学校学习更多的技术

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

    class Master(object):
        def __init__(self):
            self.mifang = '独门绝技'
        def make_cake(self):
            print(f'使用{self.mifang}制作煎饼果子')
    class School(object):
        def __init__(self):
            self.mifang = '新式秘方'
        def make_cake(self):
            print(f'使用{self.mifang}制作煎饼果子')
    class Prentice(Master,School):
        pass
    tuer = Prentice()
    tuer.make_cake()
    '''
    输出:
    使用独门绝技制作煎饼果子
    '''

    结论:如果一个类同时继承多个父类,优先继承第一个父类的同名属性和方法

    4.子类重写父类同名属性和方法

    故事:徒弟掌握师傅和学校的技术后,自己潜心研究出了自己的独门秘方

    class Master(object):
        def __init__(self):
            self.mifang = '独门绝技'
        def make_cake(self):
            print(f'使用{self.mifang}制作煎饼果子')
    class School(object):
        def __init__(self):
            self.mifang = '新式秘方'
        def make_cake(self):
            print(f'使用{self.mifang}制作煎饼果子')
    class Prentice(Master,School):
        def __init__(self):
            self.mifang = '自创秘方'
        def make_cake(self):
            print(f'使用{self.mifang}制作煎饼果子')
    tuer = Prentice()
    tuer.make_cake()
    '''
    输出:
    使用自创秘方制作煎饼果子
    '''

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

    5.拓展:__mro__   子类继承的父类以及继承顺序

    class Master(object):
        def __init__(self):
            self.mifang = '独门绝技'
        def make_cake(self):
            print(f'使用{self.mifang}制作煎饼果子')
    class School(object):
        def __init__(self):
            self.mifang = '新式秘方'
        def make_cake(self):
            print(f'使用{self.mifang}制作煎饼果子')
    class Prentice(Master,School):
        def __init__(self):
            self.mifang = '自创秘方'
        def make_cake(self):
            print(f'使用{self.mifang}制作煎饼果子')
    tuer = Prentice()
    tuer.make_cake()
    print(Prentice.__mro__)
    '''
    输出:
    使用自创秘方制作煎饼果子
    使用自创秘方制作煎饼果子
    (<class '__main__.Prentice'>, <class '__main__.Master'>, <class '__main__.School'>, <class 'object'>)
    '''

    6.子类调用父类的同名属性和方法

    class Master(object):
        def __init__(self):
            self.mifang = '独门绝技'
        def make_cake(self):
            print(f'使用{self.mifang}制作煎饼果子')
    class School(object):
        def __init__(self):
            self.mifang = '新式秘方'
        def make_cake(self):
            print(f'使用{self.mifang}制作煎饼果子')
    class Prentice(Master,School):
        def __init__(self):
            self.mifang = '自创秘方'
        def make_cake(self):
            # 再次调用初始化的原因:这里想要调用自己的同名属性和方法,但属性在其他类被init初始化位置,所以需要再次调用
            self.__init__()
            print(f'使用{self.mifang}制作煎饼果子')
    
        #子类调用父类的同名属性和方法:把父类的同名属性和方法再次封装
        def Master_make_cake(self):
            #再次调用初始化的原因:这里想要调用父类的同名属性和方法,属性在子类被init初始化位置,所以需要再次调用
            Master.__init__(self)
            Master.make_cake(self)
        def School_make_cake(self):
            School.__init__(self)
            School.make_cake(self)
    tuer =Prentice()
    tuer.make_cake()
    tuer.Master_make_cake()
    tuer.School_make_cake()
    '''
    输出:
    使用自创秘方制作煎饼果子
    使用独门绝技制作煎饼果子
    使用新式秘方制作煎饼果子
    '''

    7.多层继承

    class Master(object):
        def __init__(self):
            self.mifang = '独门绝技'
        def make_cake(self):
            print(f'使用{self.mifang}制作煎饼果子')
    class School(object):
        def __init__(self):
            self.mifang = '新式秘方'
        def make_cake(self):
            print(f'使用{self.mifang}制作煎饼果子')
    class Prentice(Master,School):
        def __init__(self):
            self.mifang = '自创秘方'
        def make_cake(self):
            # 再次调用初始化的原因:这里想要调用自己的同名属性和方法,但属性在其他类被init初始化位置,所以需要再次调用
            self.__init__()
            print(f'使用{self.mifang}制作煎饼果子')
    
        #子类调用父类的同名属性和方法:把父类的同名属性和方法再次封装
        def Master_make_cake(self):
            #再次调用初始化的原因:这里想要调用父类的同名属性和方法,属性在子类被init初始化位置,所以需要再次调用
            Master.__init__(self)
            Master.make_cake(self)
        def School_make_cake(self):
            School.__init__(self)
            School.make_cake(self)
    class Tusun(Prentice):
        pass
    tuer =Tusun()
    tuer.make_cake()
    tuer.Master_make_cake()
    tuer.School_make_cake()
    '''
    输出:
    使用自创秘方制作煎饼果子
    使用独门绝技制作煎饼果子
    使用新式秘方制作煎饼果子
    '''

     8.super()调用父类方法

    带参数写法

    super(当前类名,self).函数()

    class Master(object):
        def __init__(self):
            self.mifang = '独门绝技'
        def make_cake(self):
            print(f'使用{self.mifang}制作煎饼果子')
    class School(Master):
        def __init__(self):
            self.mifang = '新式秘方'
        def make_cake(self):
            print(f'使用{self.mifang}制作煎饼果子')
    
        #在这里调用super方法, 才能调用Master父类里的方法和属性
        def make_cake(self):
            super(School, self).__init__()
            super(School, self).make_cake()
    
    class Prentice(School):
        def __init__(self):
            self.mifang = '自创秘方'
        def make_cake(self):
            # 再次调用初始化的原因:这里想要调用自己的同名属性和方法,但属性在其他类被init初始化位置,所以需要再次调用
            self.__init__()
            print(f'使用{self.mifang}制作煎饼果子')
    
        #子类调用父类的同名属性和方法:把父类的同名属性和方法再次封装
        def Master_make_cake(self):
            #再次调用初始化的原因:这里想要调用父类的同名属性和方法,属性在子类被init初始化位置,所以需要再次调用
            Master.__init__(self)
            Master.make_cake(self)
        def School_make_cake(self):
            School.__init__(self)
            School.make_cake(self)
    
        def make_waht_cake(self):
            super(Prentice, self).__init__()
            super(Prentice, self).make_cake()
    
    tuer =Prentice()
    tuer.make_waht_cake()
    tuer.make_cake()
    '''
    输出:
    使用独门绝技制作煎饼果子
    使用自创秘方制作煎饼果子
    '''

    无参数写法

    class Master(object):
        def __init__(self):
            self.mifang = '独门绝技'
        def make_cake(self):
            print(f'使用{self.mifang}制作煎饼果子')
    class School(Master):
        def __init__(self):
            self.mifang = '新式秘方'
        def make_cake(self):
            print(f'使用{self.mifang}制作煎饼果子')
    
        #在这里调用super方法, 才能调用Master父类里的方法和属性
        def make_cake(self):
            super().__init__()
            super().make_cake()
    
    class Prentice(School):
        def __init__(self):
            self.mifang = '自创秘方'
        def make_cake(self):
            # 再次调用初始化的原因:这里想要调用自己的同名属性和方法,但属性在其他类被init初始化位置,所以需要再次调用
            self.__init__()
            print(f'使用{self.mifang}制作煎饼果子')
    
        #子类调用父类的同名属性和方法:把父类的同名属性和方法再次封装
        def Master_make_cake(self):
            #再次调用初始化的原因:这里想要调用父类的同名属性和方法,属性在子类被init初始化位置,所以需要再次调用
            Master.__init__(self)
            Master.make_cake(self)
        def School_make_cake(self):
            School.__init__(self)
            School.make_cake(self)
    
        def make_waht_cake(self):
            super().__init__()
            super().make_cake()
    
    tuer =Prentice()
    tuer.make_waht_cake()
    tuer.make_cake()
    '''
    输出:
    使用独门绝技制作煎饼果子
    使用自创秘方制作煎饼果子
    '''

    注意:使用super()可以自动查找父类。调用顺序遵循__mro__类属性的顺序。比较适合单继承使用。

    9.私有权限

    9.1定义私有属性和方法

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

    设置私有权限的方法:在属性名和方法名前面加两个_

    class Master(object):
        def __init__(self):
            self.mifang = '独门绝技'
        def make_cake(self):
            print(f'使用{self.mifang}制作煎饼果子')
    class School(object):
        def __init__(self):
            self.mifang = '新式秘方'
        def make_cake(self):
            print(f'使用{self.mifang}制作煎饼果子')
    class Prentice(Master,School):
        def __init__(self):
            self.mifang = '自创秘方'
            self.__caichan = '2个亿'
        def make_cake(self):
            # 再次调用初始化的原因:这里想要调用自己的同名属性和方法,但属性在其他类被init初始化位置,所以需要再次调用
            self.__init__()
            print(f'使用{self.mifang}制作煎饼果子')
    
    
        def __caichan(self):
            print('这是私有方法')
    
    
        #子类调用父类的同名属性和方法:把父类的同名属性和方法再次封装
        def Master_make_cake(self):
            #再次调用初始化的原因:这里想要调用父类的同名属性和方法,属性在子类被init初始化位置,所以需要再次调用
            Master.__init__(self)
            Master.make_cake(self)
        def School_make_cake(self):
            School.__init__(self)
            School.make_cake(self)
    class Tusun(Prentice):
        pass
    tuer =Tusun()
    # print(tuer.caichan)
    #print(tuer.__caichan)
    # tuer.caichan()
    # tuer.__caichan()

    四个调用都会报错,因为父类不能将私有属性和方法继承给子类

    9.2获取和修改私有属性值

    在python中,一般定义函数名get_xx用来获取私有属性,定义set_xx用来修改私有属性值

    class Master(object):
        def __init__(self):
            self.mifang = '独门绝技'
        def make_cake(self):
            print(f'使用{self.mifang}制作煎饼果子')
    class School(object):
        def __init__(self):
            self.mifang = '新式秘方'
        def make_cake(self):
            print(f'使用{self.mifang}制作煎饼果子')
    class Prentice(Master,School):
        def __init__(self):
            self.mifang = '自创秘方'
            self.__caichan = 200000
    
        def __caichan(self):
            print('这是私有方法')
    
        # 获取私有属性
        def get_caichan(self):
            return self.__caichan
    
        #修改私有属性
        def set_caichan(self):
            self.__caichan = 50000
    
        def make_cake(self):
            # 再次调用初始化的原因:这里想要调用自己的同名属性和方法,但属性在其他类被init初始化位置,所以需要再次调用
            self.__init__()
            print(f'使用{self.mifang}制作煎饼果子')
    
        #子类调用父类的同名属性和方法:把父类的同名属性和方法再次封装
        def Master_make_cake(self):
            #再次调用初始化的原因:这里想要调用父类的同名属性和方法,属性在子类被init初始化位置,所以需要再次调用
            Master.__init__(self)
            Master.make_cake(self)
        def School_make_cake(self):
            School.__init__(self)
            School.make_cake(self)
    class Tusun(Prentice):
        pass
    tuer =Tusun()
    print(tuer.get_caichan())
    tuer.set_caichan()
    print(tuer.get_caichan())
    '''
    输出:
    200000
    50000
    '''

    获取和修改私有属性不一定是get_xx和set_xx,这只是工作习惯

    总结

    继承的特点

      子类默认拥有父类的所有属性和方法

      子类重写分类同名属性和方法  

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

    super()快速调用父类方法

    私有权限

      不能继承给子类的属性和方法需要添加私有权限

      语法:

        class 类名()

          #私有属性

          __属性名 = 值

          #私有方法

          def  __函数名(self):

            代码

  • 相关阅读:
    基于Visual C++2013拆解世界五百强面试题--题9-找出所有的排列方式
    基于Visual C++2013拆解世界五百强面试题--题8-数组的排序和查找
    基于Visual C++2013拆解世界五百强面试题--题7-链表的各种操作
    宣布在 Azure 镜像库中正式推出 Windows Server 2012 R2 并降低 Windows Azure 的实例定价
    基于Visual C++2013拆解世界五百强面试题--题6-double类型逆序
    基于Visual C++2013拆解世界五百强面试题--题5-自己实现strstr
    Paging
    Swapping
    Partitioning
    Stationary point
  • 原文地址:https://www.cnblogs.com/scheduled/p/13903818.html
Copyright © 2011-2022 走看看