1:继承的写法形式:
class Father:
pass
class Son(Father):
pass
上面的这个Father称为父类、基类 下面Son这个类称为子类 派生类 一般情况下父类-子类是一对叫法,基类和派生类是一对叫法
2:子类会继承父类的所有方法
class Father:
def fun1(self):
print('Father.fun1')
def fun2(self):
print('Father.fun2')
class Son(Father):
def fun3(self):
print('Son.fun3')
obj = Son()
obj.fun1()
obj.fun3()
obj对象可以正常调用父类和子类的方法 打印结果为 Father.fun1 Son.fun3
3: 父类的函数在子类重写,有些时候父类的函数不能满足实现的需求,需要从子类重写改函数,父类的函数将不再执行
class Father:
def fun1(self):
print('Father.fun1')
def fun2(self):
print('Father.fun2')
class Son(Father):
def fun3(self):
print('Son.fun3')
def fun1(self):
print('Son.fun1')
obj = Son()
obj.fun1()
obj.fun3()
子类Son中重写了父类的fun1的函数,到通过obj实例对象调用fun1方法时,调用的是Son类中重写的方法。执行结果为Son.fun1 Son.fun3
4 如果想在重写的方法内执行父类的方法,类似于在父类的方法中扩展功能。有两种办法可以实现。
def fun1(self):
print('Son.fun1')
super(Son, self).fun1()
Father.fun1(self)
第一种是通过super(Son,self).fun1() 另一种形式Father.fun1(self),这里注意第二种方式的self参数必须存在。第一种方式的super(子类,self).fun()是固定写法。
5 支持多重继承
形式:
class Son(Father,Father1):
当多个父类中有相同的函数时,多重继承中查找函数的原则为:
1:左侧优先
2:如果没有共同的基类,就一条路径走到底,没找到,切换另一条路径
3:如果有共同的基类,先一条路径走,但不走共同基类,所有路径遍历完成,最后走基类
举例如下:
class Father:
def fun1(self):
print('Father.fun1')
def fun2(self):
print('Father.fun2')
class Father1:
def fun1(self):
print('Father1.fun1')
def fun5(self):
print('Father1.fun5')
class Son(Father,Father1):
pass
obj = Son()
obj.fun1()
Father和Father1类中都有fun1方法,按照从左到右的原则,直接结果为Father.fun1
class Base:
def fun1(self):
print('Base.fun1')
class Father(Base):
def fun3(self):
print('Father.fun1')
def fun2(self):
print('Father.fun2')
class Father1:
def fun1(self):
print('Father1.fun1')
def fun5(self):
print('Father1.fun5')
class Son(Father,Father1):
pass
obj = Son()
obj.fun1()
Father类继承Base类,Father1类没继承Base类,无共同的基类,按照一条路径走到底的执行方法,结果为Base.fun1
class Base:
def fun1(self):
print('Base.fun1')
class Father(Base):
def fun3(self):
print('Father.fun1')
def fun2(self):
print('Father.fun2')
class Father1(Base):
def fun1(self):
print('Father1.fun1')
def fun5(self):
print('Father1.fun5')
class Son(Father,Father1):
pass
obj = Son()
obj.fun1()
Father类和Father1继承共同Base类,在Father类中没发现fun1方法,因为有共同的基类,不会继续往上找,而是切换另一条路径,在Father1类中发现fun1方法,故结果非Father1.fun1,如果Father1中也没有的话,就回去共同的基类Base类去找。
6:多重继承的执行流程,在这里记住self代指调用方法的对象,这是关键。代码如下
class BaseReuqest:
def __init__(self):
print('BaseReuqest.init')
class RequestHandler(BaseReuqest):
def __init__(self):
print('RequestHandler.init')
BaseReuqest.__init__(self)
def serve_forever(self):
# self,是obj
print('RequestHandler.serve_forever')
self.process_request()
def process_request(self):
print('RequestHandler.process_request')
class Minx:
def process_request(self):
print('minx.process_request')
class Son(Minx, RequestHandler):
pass
执行代码如下obj = Son() 因为创建实例对象,会默认找__init__函数,在Son下未发现_init__函数,则去Minx, RequestHandler类中去找,Minx类中也未发现__init__,则去RequestHandler类去找,发现_init__函数,则执行打印RequestHandler.init,到现在为止,寻找__inti__函数的过程已经结束了。函数代码中还有调用BaseReuqest类中__init__方法,则去调用打印BaseReuqest.init。这行obj = Son() 代码就执行结束了。
执行obj.serve_forever()函数时,此时obj代指的是Son实例对象,在Son类下未发现serve_forever方法,则去父类中去找,先从Minx类中去找,未找到,则去RequestHandler类去找,发现serve_forever函数,执行打印RequestHandler.serve_forever完后,继续执行self.process_request(),这里self代指obj实例对象,即等价于obj.process_request(),相当于obj重新去寻找process_request(),在Son类下未发现process_request方法,则去父类中去找,先从Minx类中去找,找到process_request方法,执行,打印minx.process_request。
当执行这两行代码时
duixiang = Son() duixiang.serve_forever()
执行结果如下:
RequestHandler.init
BaseReuqest.init
RequestHandler.serve_forever
minx.process_request