继承
继承是一种创建新类的方式,新建的类可以继承一个或者多个父类,父类又称为基类,新建的类称为子类或派生类,继承一个类,父类中的属性和方法就在子类中。
子类可以继承父类的属性和方法,从而解决代码冗余问题。
单继承和多继承
class A: # 定义父类
pass
class B: # 定义父类
pass
class C(A): # 单继承,A是父类,C是子类
pass
class D(A, B): # python支持多继承,用逗号隔开多个继承的类
pass
查看继承
print(D.__bases__) #__bases__可以查看所有继承的父类
经典类和新式类
新式类
只要继承object类,就是新式类
Python3中默认继承object类,Python2中需要显示的指定继承object类
经典类
没有继承object类,就是经典类
Python2中才有经典类,python3中没有
继承顺序(菱形问题)
菱形问题
继承的菱形问题(显示的都是继承一个类,但不能是object类),新式类和经典类的查找顺序是不一样的
新式类的查找顺序:广度优先
经典类的查找顺序:深度优先
新式类:从左侧开始寻找,一直往上找,找到菱形顶点(不包括菱形顶点)后,继续下一条线的寻找,直到最后一条线找到菱形顶点(包括菱形顶点),然后结束
经典类:从左侧开始寻找,一直往上找,找到菱形顶点(包括菱形顶点)后,继续下一条线的寻找,直到最后一条线找到菱形顶点(不包括菱形顶点),然后结束
注
-
在Python3中都是新式类
-
在Python2中才区分新式类和经典类
-
不出现菱形问题,正常的查找方式
mro列表
继承顺序查找列表
class A:
pass
class B:
pass
class C:
pass
class D(A, C, B):
pass
print(D.mro())
# [<class '__main__.D'>, <class '__main__.A'>, <class '__main__.C'>, <class '__main__.B'>, <class 'object'>]
重用父类方法的两种方式
方式一
指名道姓的使用,即父类名.父类方法(),跟继承没有关系
class Person:
school = 'oldboy'
def __init__(self, name, age):
self.name = name
self.age = age
class Student:
def __init__(self, name, age):
Person.__init__(self, name, age)
stu1 = Student('xiaowu', 18)
print(stu1.name)
print(stu1.age)
# xiaowu
# 18
方式二
通过super关键字,跟继承有关,有继承才能使用
class Person:
school = 'oldboy'
def __init__(self, name, age):
self.name = name
self.age = age
class Student(Person):
def __init__(self, name, age):
super().__init__(name, age)
stu1 = Student('xiaowu', 18)
print(stu1.name)
print(stu1.age)
# xiaowu
# 18
了解
super(类名, 对象) # 在Python2中必须这么使用
super() # 在Python3中,可以直接使用
super(类名, 对象) # 在Python3中,这么使用是为了兼容Python2
总结
有继承关系的时候,通常使用super
指名道姓的方式在什么时候用?
- 没有继承关系的时候
- 继承多个父类的情况下,super是严格按照mro列表寻找,如果想指名道姓的想使用某个父类中的某个方法,就需要使用指名道姓的方式了