我是励志哥

继承补充

什么是继承?

  它是一种新建类的方式,继承了一个类,类中的属性和方法就在子类中

  父类就是基类, 子类就是派生类

  拓展: 开发工具IDE: vscode, pycharm, sumlinetext

       开发Java: eclipse, myeclipse, idea

     开发安卓: eclipse+adt,   Androidstudio: 基于idea+adt改的

  新式类: 只要继承了object类,就是新式类,Python3中默认继承object类,python2中,需要显示指定的继承object

  经典类: 没有继承object的类,就是经典类,Python3中没有经典类,Python2中才会有

class A(object):
    pass
class B(A):
    pass


# 查看类名
print(B.__name__)


输出: B

# 查看父类
print(B.__bases__)   # B的所有的父类

输出为(<class '__main__.A'>,)

  

二. 属性查找的菱形问题:

class people
    school = 'peking university'




class Teacher(people):
    def __init__(self, name, age, level)
            self.name = name
            self.age = age
            self.level = level

class Student(people):
    def __init__(self, name, age, level)
            self.name = name
            self.age = age
            self.level = level


stu1 = Student('bgon', 85, "python")   # 实例化一个对象
print(stu1.school)   # 学生类中并没school这个属性,他在父类中定义的



# 输出结果为: peking university

  如果这样继承的话,那么问题就来了,如何重用父类的属性,属性的查找顺序是什么,又是如何重用父类的方法?

  我们之前说过查找对象顺序是: 先找对象===>类中找===>父类中找===>报错,但是呢,今天不一样,在父类中继承了好几个,也就是多继承,那又是如何去寻找?

三. 重用父类的方法

class people
    school = 'peking university'
    def __init__(self, name, age, level)
            self.name = name
            self.age = age
            self.level = level



class Teacher(people):
    def __init__(self, name, age, level)
            self.name = name
            self.age = age
            self.level = level

class Student(people):
    def __init__(self, name, age, couse)
            self.name = name
            self.age = age
            self.couse = couse


stu1 = Student('bgon', 85, "python")   # 实例化一个对象
print(stu1.school)   # 学生类中并没school这个属性,他在父类中定义的

  上面继承中可以看出,代码出现了冗余,那我们如何重用父类的__init__方法呢,我们先看第一种方法: 指名道姓的使用(跟继承无关)

class people
    school = 'peking university'
    def __init__(self, name, age, level)
            self.name = name
            self.age = age
            self.level = level

class Teacher(people):
    def __init__(self, name, age, level)
            self.name = name
            self.age = age
            self.level = level

class Student(people):
    def __init__(self, name, age, couse)
            people.__init__(self, age,name)
            self.couse = couse

  方式二: 通过super关键字

class people
    school = 'peking university'
    def __init__(self, name, age, level)
            self.name = name
            self.age = age
            self.level = level

class Teacher(people):
    def __init__(self, name, age, level)
            self.name = name
            self.age = age
            self.level = level

class Student(people):
    def __init__(self, name, age, couse)
            super().__init__(name, age)
            self.couse = couse

  super()会按照mro列表拿到父类对象,对象来调用绑定方法, 不需要传递第一个参数(self),所以有__init__(name, age)

class people
    school = 'peking university'
     def __init__(self, name, age)
            self.name = name
            self.age = agel

class Teacher(people):
    pass

class Student(people):
     pass

stu1 = Student('bgon', 85)   # 实例化一个对象
print(stu1.school)   # 学生类中并没school这个属性,他在父类中定义的

  类实例化会自动调用__init__,如果类中没有,就去父类中去寻找

多层继承:

class A:
    a = "AAAA"
pass class B(A): a = "BBBB"
  pass class C(B): a = "CCCC"
pass class D(C): a = "DDDD
   pass d = D() print(d, a) # 输出为DDDD

  

多继承:

class A:
    a = "AAAA"
    pass
class B:
    a = "BBBB"
  pass
class C:
    a = "CCCC"
     pass
class D(A, B, C):
    a = "DDDD
   pass


d = D()
print(d, a)

  那上面的查找顺序又是怎样的呢? 首先还是先从自己找起,当D中没有a的值时,先找A,然后依次是,B,C

继承的菱形问题(显式的都继承一个类,不是object类):

  在新式类和经典类的查找顺序是不一样的, 新式类的查找顺序是广度优先(从左侧开始,,一直往上找,找到菱形的顶点结束(不包括菱形顶点),继续下一个继承的父往上找,找到菱形的顶点结束(不包括菱形顶点)),经典类的查找顺序是深度优先(从左侧开始,,一直往上找,找到菱形的顶点结束(包括菱形顶点))==>一条道找到底然后再去广度上找

class A(object):
    def test(self):
        print('from A')

class B(A):
    def test(self):
        print('from B')

class C(A):
    def test(self):
        print('from C')

class D(B):
    def test(self):
        print('from D')

class E(C):
    def test(self):
        print('from E')

class F(D,E):
    # def test(self):
    #     print('from F')
    pass
f1=F()
f1.test()
print(F.__mro__) #只有新式才有这个属性可以查看线性列表,经典类没有这个属性   super是严格按照mro列表找

#新式类继承顺序:F->D->B->E->C->A
#经典类继承顺序:F->D->B->A->E->C
#python3中统一都是新式类
#pyhon2中才分新式类与经典类

  

所有的父类都到顶,才叫菱形问题,也就是说有一个总要继承object

 

posted @ 2019-10-02 18:40  python黑客编程  阅读(186)  评论(0编辑  收藏  举报