zoukankan      html  css  js  c++  java
  • Python 继承

    何为继承?

    继承是一种创建新类的方式,在python中,新建的类可以继承一个或多个父类,父类又可称为基类或超类,新建的类称为派生类或子类。

    先举一个例子,如:

    class animal:
        def __init__(self,name,kind,food,language):
            self.name = name
            self.kind = kind
            self.food = food
            self.language = language
        def yell(self):
            print('%s叫' % self.language)
        def eat(self):
            print('吃%s' % self.food)
        def drink(self):
            print('喝水')
    class cat(animal):
        def catch_mouse(self):
            print('抓老鼠')
    class dog(animal):
        def look_after_house(self):
            print('看家')
    Ali = cat('Ali', 'bosi_cat', 'fish', 'miaomiao')
    Jingang = dog('Jingang','aisijimo_dog', 'paigu', 'wangwang')
    Ali.yell()
    Ali.catch_mouse()
    Ali.drink()
    Jingang.yell()
    Jingang.eat()
    Jingang.look_after_house()

    从上面可以看出,cat与dog类为子类,而animal为父类,当实例化cat类调用yell方法时,首先会去子类中寻找,当找不到时,再去父类中寻找,从而调用。实例化dog类也是一样。

    class animal:
        def __init__(self, name, kind, food, language):
            # print('in animal')
            self.name = name
            self.king = kind
            self.food = food
            self.language = language
        def yell(self):
            print('%s叫'% self.language)
        def eat(self):
            print('吃%s' % self.food)
        def drink(self):
            print('喝水')
    
    class cat(animal):
    
        def __init__(self, name, kind, food, language, eye_color):
            # print('in cat')
            self.eye_color = eye_color   # 派生类属性
            # animal.__init__(self, name, kind, food, language)   # 调用父类的方法
            super().__init__(name,kind,food,language)    # 调用父类 __init__
    
        def catch_mouse(self):
            print('抓老鼠')
        def eat(self):        # 不仅执行了父类中的基础功能,还完成了特殊的功能
            animal.eat(self)
            super().eat()
            self.weight = 10   # 方法内定义属性
    
    class dog(animal):
        def look_after_house(self):
            print('看家')
        def eat(self):
            animal.eat(self)
            super().eat()
            self.drink()
    Ali = cat('Ali', 'bosi_cat', 'fish', 'miaomiao','绿色')
    print(Ali.food)
    Ali.eat()
    Ali.catch_mouse()
    print(Ali.weight)

    从上面分析可知:

    当子类当中有被调用的方法时,子类的对象会直接选择子类中的方法,变量,父类中的方法不会被自动执行

    如果我们既要想执行子类方法,又想执行父类的方法,那么需要在子类的方法中调用父类的方法:

    父类名.方法名(self,...(参数))super().方法名((没有self)...(参数))

    上面使用的好处:可以帮助我们在子类中调用父类中的同名方法

    面试题:

    下面几道题为面试常考题,进行分析下:

    # 例1
    class Foo:
        def __init__(self):
            self.func()
        def func(self):
            print('in Foo')
    
    class Son(Foo):
        def func(self):
            print('in Son')
    
    s1 = Son()    # in Son
    # 解题思路:
    1 将Son类实例化给s1
    2 在son类中寻找__init__方法,如果没有,就去父类Foo中寻找
    3 自动执行父类中的__init__方法,此时,self始终为s1,因此,该内部调用的方法为:s1.func()
    4 返回到Son类中,打印输出'in Son'
    # 例2:
    class Foo:
        Country = 'China'
        def func(self):
            print(self.Country)
    
    class Son(Foo):
        Country = 'English'
        def func(self):     # 走这个方法
            print(self.Country)
    
    s = Son()
    s.func()   # English
    # 例3:
    class Foo:
        Country = 'China'
        def func(self):  # 走这个方法
            print(self.Country)
    
    class Son(Foo):
        Country = 'English'
    
    s = Son()
    s.func()   # English
    # 解题思路:
    1 实例化对象s,开辟类对象空间存储属性 即Country = 'English'
    2 调用子类空间func()函数,若没有,去父类去寻找,
    3 此时父类中的self为实例化对象s,因此,打印输出的为:English
    # 例4:
    class Foo:
        Country = 'China'
        def func(self):
            print(self.Country)
    
    class Son(Foo):pass
    
    s = Son()
    s.func()   # 'China'
    解题思路:
    1 同上,子类中没有属性与方法
    2 调用父类属性与方法,进行输出

    多继承

    什么是多继承?多继承可表示为:

    class Parent1:pass
    class Parent2:pass
    class Son(Parent1,Parent2):pass
    print(Son.__bases__)    # (<class '__main__.Parent1'>, <class '__main__.Parent2'>)

    上式中,Son类为子类,父类为:Parent1与Parent2。在该继承方式中,Son类同时继承了两父类其查询方式又是怎样的呢?

    class F1:
        def a(self):
            print('F1.a')
    class F2:
        def a(self):
            print('F2.a')
    class S(F1,F2):
        pass
    obj = S()
    obj.a()   # F1.a
    class F0:
        def a(self):
            print('F0.a')
    
    class F1(F0):
        def a1(self):
            print('F1.a')
    class F2:
        def a(self):
            print('F2.a')
    class S(F1,F2):
        pass
    obj = S()
    obj.a()   # F0.a
    运行下查找顺序:
    python中支持多继承
    a. 左侧优先
    b. 一条道走到黑
    c. 有同一个根时,根最后执行
    class Base():
        def a(self):
            print('Base.a')
    
    class F0(Base):
        def a(self):
            print('F0.a')
    
    class F1(F0):
        def a1(self):
            print('F1.a')
    
    class F2(Base):
        def a(self):
            print('F2.a')
    
    class S(F1,F2):
        pass
    
    obj = S()
    obj.a()

    再举一个例子:

    class RequestHandler():
        def serve_forever(self):
            print('RequestHandler.serve.forever')
            self.process_request()
        def process_request(self):
            print('process_request.process_request')
    
    class Minx:
        def process_request(self):
            print('minx.process_request')
    
    class Son(Minx, RequestHandler):
        pass
    
    obj = Son()
    obj.serve_forever()

    说明:

    函数内部self 指的就是对象obj。因此,在调用obj.serve_forever()时候,首先在派生类Son中找有没有serve_forever()函数,
    若没有,则去Son中的父类Minx类去找,也没有后,在返回到父类RequestHandler()中去找,找到后执行并打印,当运行到
    self.process_request()函数时,此时self 不是RequestHandler()函数内部的process_request(self),而是obj对象的的self,
    即Son类的self,因此,又得重新从派生类按顺序去寻找process_request()函数,最后在父类Minx中找到!
    class BaseRequest:
        def __init__(self):
            print('BaseRequest.init')
    
    class RequestHandler(BaseRequest):
        def __init__(self):
            print('RequestHandler.init')
            BaseRequest.__init__(self)   # 执行父类的__init__(self)
        def serve_forever(self):
            print('RequestHandler.serve.forever')
            self.process_request()
        def process_request(self):
            print('process_request.process_request')
    
    class Minx:
        def process_request(self):
            print('minx.process_request')
    
    class Son(Minx, RequestHandler):
        pass
    
    obj = Son() 
    默认执行__init__(self)函数,因此在子类或着父类中按顺序寻找该函数
    obj.serve_forever() # 上面执行完了,重新执行该语句
  • 相关阅读:
    斐波那契数列相关
    社论CF1616G
    题解AGC056
    IOI2018 meetings
    题解UOJ#696. 【候选队互测2022】理论复杂度
    larval5.1模型静态使用多次出现查询属性信息存在问题
    SQL Server里面可能经常会用到的日期格式转换方法
    asp.net页面刷新后样式就发生了改变
    [武汉站]Windows 7 社区发布活动
    C++/CLI学习入门数组
  • 原文地址:https://www.cnblogs.com/colin1314/p/9551215.html
Copyright © 2011-2022 走看看