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  :

    def fun1(self):
        print(\' .fun1\')

class Father( ):

    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类继承 类,Father1类没继承 类,无共同的基类,按照一条路径走到底的执行方法,结果为 .fun1

class  :

    def fun1(self):
        print(\' .fun1\')

class Father( ):

    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类和Father1继承共同 类,在Father类中没发现fun1方法,因为有共同的基类,不会继续往上找,而是切换另一条路径,在Father1类中发现fun1方法,故结果非Father1.fun1,如果Father1中也没有的话,就回去共同的基类 类去找。

6:多重继承的执行流程,在这里记住self代指调用方法的对象,这是关键。代码如下

class  Reuqest:

    def __init__(self):
        print(\' Reuqest.init\')


class RequestHandler( Reuqest):
    def __init__(self):
        print(\'RequestHandler.init\')
         Reuqest.__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__函数的过程已经结束了。函数代码中还有调用 Reuqest类中__init__方法,则去调用打印 Reuqest.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
Reuqest.init
RequestHandler.serve_forever
minx.process_request
 

这里一定要牢记:self永远是执行该方法的调用者,在按照寻找的原则去查找。

收藏 打印