继承
一、继承
承是一种创建新类的方式,新建的类可以继承一个或多个父类(python支持多继承),父类又可称为基类或超类,新建的类称为派生类或子类。
子类会继承父类的属性,解决代码过长冗余
继承的分类:新式类、经典类。
新式类:继承了object类就是新式类,python 3中,默认都继承object类,因此都是新式类。二在python 2中只有显式指定继承object才是新式类。
经典类:没有继承object类的就是经典类,python 2中有经典类,python 3中没有经典类
class A(object):
pass
class C:
pass
#B继承了A,C这个类
class B(A,C):
pass
print(C.__bases__)
二、利用继承减少代码冗余
在开发程序的过程中,如果我们定义了一个类A,然后又想新建立另外一个类B,但是类B的大部分内容与类A的相同,我们不可能从头开始写一个类B,这就用到了类的继承的概念。
通过继承的方式新建类B,让B继承A,B会‘遗传’A的所有属性(数据属性和函数属性),实现代码重用。
class Person(object):
school = 'jialidun'
def __init__(self,name,age):
self.name = name
self.age = age
class Teacher(Person):
pass
class Student(Person):
pass
# 类实例化会自动调用__init__如果类中没有,去父类中找
# stu1=Student() #报错,因为父类中必须传两个参数
stu1 = Student('xian_hu',20)
print(stu1.name)
print(stu1.age)
print(stu1.school)
stu1.school='xxx'
print(stu1.school)
xiao_hu
18
jialidun
xxx
2.1 多层继承
class A:
a = 'AAAA'
class B(A):
a = 'BBBB'
class C (B):
a = 'CCCC'
class D(C):
pass
d = D()
print(d.a)
CCCC
多层继承为一次向上继承
2.2 多继承
class A:
a="AAAA"
pass
class B:
a="BBB"
pass
class C:
a="CCC"
pass
class D(A,B,C):
pass
d=D()
print(d.a)
AAAA
class A:
# a="AAAA"
pass
class B:
a="BBB"
pass
class C:
a="CCC"
pass
class D(A,B,C):
pass
d=D()
print(d.a)
BBB
多继承为从左至右继承
2.3 多层多继承(菱形问题)
class G(object):
a = "GGG"
pass
class F(G):
pass
class E(G):
pass
class D(G):
pass
class C(F):
pass
class B(E):
pass
class A(B,C,D):
pass
a=A()
print(a.a)
GGG
继承的菱形问题分为新式类和经典类,二者的查找顺序不同。
新式类(py3中全是新式类):广度优先---从左侧开始,一直往上找,找到菱形的顶点结束(不包括菱形顶点),继续下一个继承的父类往上找,找到菱形的顶点结束(不包括菱形顶点),最后找到菱形顶点。
经典类(只有py2中才有):深度优先---从左侧开始,一直往上找,找到菱形的顶点结束(包括菱形顶点)继续下一个继承的父类往上找,找到菱形的顶点结束(不包含菱形定点)。
三、重用父类方法
3.1 指名道姓
继承父类方法方式一:指名道姓,但是实际上并没有继承关系。使用方法是子类def + __init__直接调用父类定义的函数。
3.2 super关键字
继承父类方法方式二:super关键字。
class Person(object):
school = 'oldboy'
def __init__(self,name,age):
self.name=name
self.age=age
def study(self):
print('study....')
class Student(Person):
school = 'yyyy'
def __init__(self,name,age,course):
super().__init__(name,age)
super(Student,self).__init__(name,age)
self.course=course
def study(self):
# Person.study(self)
super().study()
# print("%s学生在学习"%self.name)
注意:super() 会按照mro列表拿到父类对象;对象来调用绑定方法,不需要传递第一个参数(self)。
super关键字方法也分别为新式类和经典类,python 3使用新式类super().方法。python 3使用super(类名,对象). 的方法。
总结:有继承关系的时候,通常用super。没有继承关系或者如果继承了多个父类,super是按照mro列表找,现在想指名道姓的用某个父类的某个方法,就需要指名道姓的使用