zoukankan      html  css  js  c++  java
  • day23:单继承&多继承&菱形继承&__init__魔术方法

    目录

    1.单继承

      1.1 关于继承的一些基本概念

      1.2 子类可以调用父类的公有成员

      1.3 子类无法调用父类的私有成员

      1.4 子类可以改写父类的方法

    2.多继承

      2.1 多继承的基本语法

      2.2 super用法

      2.3 self和super的区别

    3.菱形继承(钻石继承)

      3.1 super:用来解决复杂的多继承调用顺序

      3.2 mro列表:返回调用顺序列表

      3.3 issubclass和isinstance

    4.魔术方法__init__方法

      

    单继承

    关于继承的一些基本概念

    1.什么是子类?什么是父类?如果一个类继承另外一个类,该类叫做子类(衍生类),被继承的类叫做父类(基类,超类)

    2.继承的种类:1.单继承 2.多继承 

    3.object类:在python中,所有的类都默认继承父类object

    定义一个Human类,并定义一些属性和方法:

    class Human(object):
        hair = "黑色"
        sex = ""
    
        def cry(self):
            print("人类会哭")
        def eat(self):
            print("人类会吃东西")
        def __makebaby(self):
            print("人类会繁衍生息")

    子父继承之后,子类可以调用父类的公有成员

    # 1.子父继承之后,子类可以调用父类的公有成员
    class Man(Human): # 定义Man类,继承Human类
        pass
    
    obj = Man()
    print(obj.hair) # 子类Man直接调用父类的hair属性
    obj.cry() # 子类Man直接调用父类的cry方法

    子父继承之后,子类不能调用父类的私有成员

    # 2.子父继承之后,子类不能调用父类的私有成员
    class Woman(Human):
        def pub_func(self):
            self.__makebaby()
    
    obj = Woman()
    obj.__makebaby() # error 子类无法直接调用父类的私有成员
    obj.pub_func() # error 即使在子类定义pub_func用来存放私有成员,那也是父类的私有成员,而非子类的

    子父继承之后,子类可以改写父类中的方法

    子父继承之后

    1.如果子类里面有该成员属性或者方法,优先调用自己的

    2.如果子类没有该成员,则调用父类中的成员

    3.如果子类父类都没有该成员,则直接报错

    class Children():
        sex = ""
        def cry(self):
            print("小孩会哇哇哇哭")
    obj = Children()
    obj.cry() # 子类有cry方法,优先使用子类的

    多继承

    多继承的基本语法

    # 1.基本语法
    class Father():
        property = "爸爸英姿飒爽"
        def f_hobby(self):
            print("爸爸喜欢抽烟")
    
    class Mother():
        property = "妈妈倾国倾城"
        def m_hobby(self):
            print("妈妈喜欢打麻将")
    
    class Daughter(Father,Mother): # Daughter类继承Father类和Mother类
        pass
    
    # 实例化对象
    obj = Daughter()
    print(obj.property) # 优先会继承Father类的property
    obj.m_hobby() # 妈妈喜欢打麻将

    super用法

    1.super本身是一个类,super()是一个对象,用来调用父类的绑定方法

    2.super()只应用在绑定方法中,默认自动传递self对象(前提super所在作用域存在self)

    3.super用途:解决复杂的多继承调用顺序

    class Father():
        property = "爸爸英姿飒爽"
        def f_hobby(self):
            print("爸爸喜欢抽烟")
    
    class Mother():
        property = "妈妈倾国倾城"
        def m_hobby(self):
            print("妈妈喜欢打麻将")
    
    class Son(Father,Mother):
        property = "儿子喜欢玩游戏"
    
        # 1.利用类来调用父类的成员
        def skill1(self):
            Father.f_hobby()
            print(Mother.property)
        # 2.利用对象调用父类的成员
        def skill2(self):
            self.m_hobby()
            print(self.property)
        # 3.利用super调用父类的属性和方法
        """
        super()只调用父类的相关公有成员,不会调用自己的本类成员,父类没有直接报错
        super()在调用父类方法时,只调用父类的绑定方法,默认传递参数是本类的对象self
        """
        def skill3(self):
            print(super().property)
            super().m_hobby()
    
    obj = Son()
    obj.skill1()
    obj.skill2()
    obj.skill3()

    self和super的区别

    self和super()的区别:

    self在调用成员时,先看看自己的类对象是否存在该成员

      1.如果有调用自己的.

      2.如果子类自己没有,调用父类的

      3.如果子类和父类都没有,则直接报错

    super()在调用成员时,只调用父类的相关成员(属性,绑定方法)

      永远不会调用自己的,如果父类没有,直接报错

    菱形继承(钻石继承)

    super:用来解决复杂的多继承调用顺序

    class OldWoman():
        pass
    
    class Human():
        pty = 4
        def feelT(self):
            print("原始人类热了,吃冰块1")
            print(self.pty)
            print("原始人类冷了,生火取暖2")
    
    class Man(Human):
        pty = 3
        def feelT(self):
            print("现代男人热了,光膀子3")
            super().feelT()
            print("现代男人冷了,穿大棉袄4")
    
    class Woman(Human):
        pty = 2
        def feelT(self):
            print("现代女人热了,吹空调5")
            super().feelT()
            print("现代女人冷了,喝热水6")
    
    class Children(Man,Woman):
        pty = 1
        def feelT(self):
            print("现代小孩热了,哇哇哭7")
            super().feelT()
            print("现代小孩冷了,也要哭8")
    
    obj = Children()
    obj.feelT()

    执行顺序是73512648,继承顺序Children->Father->Mother->Human

    执行完毕之后还需要将每个类中的feelT方法中剩余的代码执行完

    整个代码的执行顺序像递归中"一来一回"的过程

    mro列表:返回调用顺序列表

    mro列表:super用途的一个体现,解决复杂的多继承调用顺序关系

    类.mro() 返回的是方法调用顺序列表,针对于多继承下的同名方法,按照顺序依次的进行调用

    lst = Children.mro()
    print(lst)
    """
    [
    <class '__main__.Children'>, 
    <class '__main__.Man'>, 
    <class '__main__.Woman'>, 
    <class '__main__.Human'>, 
    <class 'object'>
    ]
    """

    issubclass 判断子父关系 (应用在类当中,判断子父关系)

    # issubclass 判断子父关系 (应用在类当中,判断子父关系)
    """只要在一条继承链上即可(有血缘关系)"""
    res = issubclass(Children,Man)
    print(res)
    res = issubclass(Children,Woman)
    print(res)
    res = issubclass(Children,Human)
    print(res)
    res = issubclass(Children,(Human,Woman,Man,OldWoman))
    print(res)
    res = issubclass(Children,OldWoman)
    print(res)

    isinstance (应用在对象和类之间,判断类型)

    # isinstance(应用在对象和类之间,判断类型)
    """只要在一条继承链上即可(有血缘关系)"""
    res = isinstance(obj,Children) # True
    res = isinstance(obj,Human) # True
    res = isinstance(obj,(Human,Children,Woman)) # True
    res = isinstance(obj,OldWoman) # False

    问题:打印的值是多少?

    如图所示:

    魔术方法之__init__方法

    __init__方法简介

    1.触发时机:实例化对象,初始化的时候触发

    2.功能:为对象添加成员

    3.参数:参数不固定,至少一个self参数

    4.返回值:无

    基本语法

    # 1.基本语法
    class MyClass():
        def __init__(self):
            print("初始化方法被触发")
            # 为当前对象self添加成员name
            self.name = "Mike"
    # 实例化对象
    obj = MyClass() # 初始化方法被触发
    print(obj.name) # Mike

    带有多个参数的构造方法

    # 2.带有多个参数的构造方法
    class MyClass():
        def __init__(self,name):
            # self.成员名 = 参数
            self.name = name
    # 实例化对象
    obj = MyClass("Mike") # 在实例化对象的时候,给构造方法传递参数
    print(obj.name) # Mike

    类可以是一个,对象可以是多个

    1.一个类可以实例化多个不同的对象

    2.对象和对象之间彼此独立

    3.但都可以使用类中的公有成员

    class Children():
        def __init__(self, name, skin):
            self.name = name
            self.skin = skin
    
        def cry(self):
            print("小孩一出生就哇哇哇的哭")
    
        def drink(self):
            print("小孩一下生就要喝奶奶")
    
        def __la(self):
            print("小孩拉粑粑是私有的")
    
        def pub_info(self):
            print("该对象的名字是{},该对象的肤色是{}".format(self.name, self.skin))
    
    
    # 创建第一个小孩
    afanda = Children("阿凡达", "蓝色的")
    afanda.pub_info()
    afanda.cry()
    
    # 创建第二个小孩
    afanti = Children("阿凡提", "黄色的")
    afanti.pub_info()
    afanti.drink()
    
    # 创建第三个小孩
    bao = Children("我滴宝强", "绿色的")
    bao.pub_info()
    # bao.__la() # 无法在类外调用私有的成员
  • 相关阅读:
    python构造一个freebuf新闻发送脚本
    CISCO路由器练习
    python dns欺骗
    心脏滴血漏洞
    0CTF题中的神奇宝贝WP
    一套海量在线用户的移动端IM架构设计实践分享(含详细图文)(转)
    sendfile函数--零拷贝(转)
    浅谈分布式消息技术 Kafka(转)
    架构之微服务(zookeeper)转
    Zookeeper 3、Zookeeper工作原理(转)
  • 原文地址:https://www.cnblogs.com/libolun/p/13434675.html
Copyright © 2011-2022 走看看