什么是继承?
它是一种新建类的方式,继承了一个类,类中的属性和方法就在子类中
父类就是基类, 子类就是派生类
拓展: 开发工具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 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