继承类之点点滴滴

晚上都睡不着了,和萧敬腾一样,我睡了一觉却更觉得疲劳

打气!草 他 妈 的!打气!

今日洗脑金句:!!@#%¥……@!@%#¥!%

类的继承

一、什么是继承

  • 继承是一种新建类的方式,新建的类称为子类,被继承的类称为父类
  • 继承的特性是:子类会遗传父类的属性
  • 继承是类与类之间的关系

简单来讲,我是你爸爸,你是我儿子,你就继承了我的东西,我的一屁股债,以及我的脑子。

二、为什么要用继承

  • 使用继承可以减少代码的冗余(别问,问就是爸爸爱你)

三、对象的继承

  • Python中支持一个类同时继承多个父类
class Parent1:
    pass


class Parent2:
    pass


class Sub1(Parent1, Parent2):
    pass

。。。。你究竟是谁的儿子

  • 使用__bases__方法可以获取对象继承的类
print(Sub1.__bases__)

(<class 'main.Parent1'>, <class 'main.Parent2'>)

  • 在Python3中如果一个类没有继承任何类,则默认继承object类
  • 在Python2中如果一个类没有继承任何类,不会继承object类
print(Parent1.__bases__)

(<class 'object'>,)

四、类的分类

新式类:就是继承了object的类以及该类的子类,都是新式类,而且python3里面只有新式类,所有的都是。不存在经典类。

经典类:没有继承object的类以及该类的子类,都是经典类,只有python2中才有经典类。

五、对象查找属性的顺序

  • 对象查找属性的顺序:对象自己-》对象的类-》父类-》父类。。。

类的派生

一、派生是什么

  • 派生:子类中新定义的属性的这个过程叫做派生,并且需要记住子类在使用派生的属性时始终以自己的为准

1.1派生方法一(类调用)

  • 指名道姓访问某一个类的函数:该方式与继承无关
class OldboyPeople:
    """由于学生和老师都是人,因此人都有姓名、年龄、性别"""
    school = 'oldboy'

    def __init__(self, name, age, gender):
        self.name = name
        self.age = age
        self.gender = gender


class OldboyStudent(OldboyPeople):
    """由于学生类没有独自的__init__()方法,因此不需要声明继承父类的__init__()方法,会自动继承"""

    def choose_course(self):
        print('%s is choosing course' % self.name)


class OldboyTeacher(OldboyPeople):
    """由于老师类有独自的__init__()方法,因此需要声明继承父类的__init__()"""

    def __init__(self, name, age, gender, level):
        OldboyPeople.__init__(self, name, age, gender)
        self.level = level  # 派生

    def score(self, stu_obj, num):
        print('%s is scoring' % self.name)
        stu_obj.score = num


stu1 = OldboyStudent('tank', 18, 'male')
tea1 = OldboyTeacher('nick', 18, 'male', 10)
print(stu1.__dict__)
print(tea1.__dict__)

{'name': 'tank', 'age': 18, 'gender': 'male'}

{'name': 'nick', 'age': 18, 'gender': 'male', 'level': 10}

1.2 派生方法二(super)

  • 严格以来继承属性查找关系
  • super()会得到一个特殊的对象,该对象就是专门用来访问父类中的属性的(按照继承的关系)
  • super().init(不用为self传值)
  • super的完整用法是super(自己的类名,self),在python2中需要写完整,而python3中可以简写为super()
class OldboyPeople:
    school = 'oldboy'

    def __init__(self, name, age, sex):
        self.name = name
        self.age = age
        self.sex = sex


class OldboyStudent(OldboyPeople):
    def __init__(self, name, age, sex, stu_id):
        # OldboyPeople.__init__(self,name,age,sex)
        # super(OldboyStudent, self).__init__(name, age, sex)
        super().__init__(name, age, sex)
        self.stu_id = stu_id

    def choose_course(self):
        print('%s is choosing course' % self.name)


stu1 = OldboyStudent('tank', 19, 'male', 1)
print(stu1.__dict__)

{'name': 'tank', 'age': 19, 'sex': 'male', 'stu_id': 1}

通常情况下本大爷都是用super()的,java后遗症,感觉用第一种方式的话和继承没一点关系,用个几把呢?

菱形继承问题

92-菱形继承问题-经典类.png?x-oss-process=style/watermark

这张图看得懂吗,你肯定看不懂。![img](https://images.cnblogs.com/cnblogs_com/chanyuli/1515439/o_(%60@Z%7DIR0[1[(SX8CB)3CN.jpg)

就是寻找的顺序啦。

A继承了BCD三个父类,怎么找属性呢,按顺序来,从左到右,从下到上,真色情啊,就是上面这个图的意思了。

但是,这是python2里的搜索方式,也叫深度优先搜索,找到一个父类,直接干到底,再去干第二个父类。

而在python3里,是广度优先搜索

92-菱形继承问题-新式类.png?x-oss-process=style/watermark

一旦发现自己要访问的下一个父类,有其他也会去访问,直接停住,开始走下一个父类,直到最后全部会访问完,这就是python3的广度优先搜索。

python到底是如何实现继承的,对于你定义的每一个类,python会计算出一个方法解析顺序(MRO)列表,这个MRO列表就是一个简单的所有基类的线性顺序列表,如:

print(A.mro())  # A.__mro__

[<class 'main.A'>, <class 'main.B'>, <class 'main.E'>, <class 'main.C'>, <class 'main.F'>, <class 'main.D'>, <class 'main.G'>, <class 'object'>]

也可以用这个方法来看他搜索的顺序。

好了,话不多说,几千字就够,仔细一看,这篇博客也写的挺好的,他好就好在他好tmgb

img

posted @ 2019-08-27 23:10  chanyuli  阅读(148)  评论(0编辑  收藏  举报