zoukankan      html  css  js  c++  java
  • 【python之路】【之前没搞明白】3面向对象(继承)

    文献:

    https://book.apeland.cn/details/157/

    https://docs.python.org/zh-cn/3/tutorial/classes.html#a-word-about-names-and-objects

    1 继承的语法

    继承用在这里就是字面意思,一个类可以继承另一个类的属性与方法。

    “一个类”就是子类、派生类

    “另一个类”就是父类、超类、基类

    class DerivedClassName(BaseClassName):
        <statement-1>
        ...
        <statement-N>

    名称 BaseClassName必须定义于包含子类定义的作用域中,说白了就是写在一个py文件里面。 也允许用其他任意表达式代替基类名称所在的位置。 这有时也可能会用得上,例如,当基类定义在另一个模块中的时候:

    class DerivedClassName(modname.BaseClassName):

    试了一下,在用之前一定在正在执行的py文件中先导入modname模块才行。

    # 这是modname.py文件
    class
    BaseClassName: def test(self): print('从modname的BaseClassName来的')
    # 这是正在执行的py文件
    import modname
    
    class DerivedClassName(modname.BaseClassName):
        def show(self):
            super().test()
    
    if __name__ == '__main__':
        d = DerivedClassName()
        d.show()

    结果: 从modname的BaseClassName来的 

    1.1 子类和父类中的属性和方法引用的顺序

    1、找子类的属性或方法,有则直接引用,无则2

    2、再找父类的属性或方法,有则直接引用,无则3

    3、如果父类也有父类 的话,继续递归的应用下去

    1.2 子类重写父类的方法

    官方文档所所得最直接的方法: BaseClassName.methodname(self, arguments) 

    还可以用 super().methodName() 

    class Base:
        def fun_1(self,arg):
            print('基类方法1执行结果:%s' %arg)
    
        def fun_2(self):
            print('基类方法2')
    
    class Sub(Base):
    
        def fun_3(self,arg):
            Base.fun_1(self, arg) #第一种觉得不会错
    
        def fun_4(self):
            super().fun_2() #第二种,在多继承时要注意顺序
            print('子类调用了一次基类方法fun_2') #对基类方法的扩展
    
    if __name__ == '__main__':
        s = Sub()
        s.fun_3(arg='dashabi') #基类方法1执行的结果是 dashabi
        s.fun_4() #基类方法2

    结果:

    基类方法1执行结果:dashabi
    基类方法2
    子类调用了一次基类方法fun_2

    1.3 两个内置函数的使用

    • 使用 isinstance() 来检查一个实例的类型: isinstance(obj, int) 仅会在 obj.__class__ 为 int 或某个派生自 int 的类时为 True

    • 使用 issubclass() 来检查类的继承关系: issubclass(bool, int) 为 True,因为 bool 是 int 的子类。 但是,issubclass(float, int) 为 False,因为 float 不是 int 的子类。

    2 多继承

    多继承时,继承顺序很重要,分为2种:

    深度优先:从下到上,从最下面的子类到最上面的父类

    广度优先:从左到右,类(基类左,基类右)的括号里面,从左往右

    python3内部使用的是一个混合的方法,C3算法(看的太累,https://www.python.org/download/releases/2.3/mro/)。

    很复杂,可能要花很多时间去搞清楚,但是没必要。直接调用 mro() python会告诉你顺序的。

    class A:
        def test(self):              #             A
            print('A')               #         / /                                     
    class B1(A):                     #       B1 B2   B3 B4
        def test(self):              #         /      /
            print('B1')              #         C1      C2  
    class B2(A):                     #                / 
        def test(self):              #             D
            print('B2')
    class B3(A):
        def test(self):
            print('B3')     # D > C1 > B1 > B2 > C2 > B3 > B4 > A > 'object'
    class B4(A):
        def test(self):     # object类,是python中所有类的基类,万类归宗就是object类
            print('B4')
    class C1(B1,B2):
        def test(self):
            print('C1')
    class C2(B3,B4):
        def test(self):
            print('C2')
    class D(C1,C2):
        def test(self):
            print('D')
    
    if __name__ == '__main__':
        print(D.mro())
        d = D()
        d.test()

    这里和Alex视频里面讲的顺序好像有点区别,我也不知道问题在哪里。

    3 补充的知识点:经典类和新式类

    python2定义类的为经典类和python3定义类的为新式类:

    经典类:class Foo:

    新式类:class Foo( object):

    但是在python3中,对新式类有个简便写法,就是  class Foo: ,本质上还是 class Foo( object): ,不过还是推荐使用新式类的标准写法。

     

  • 相关阅读:
    Tomcat下使用war包发布项目
    shell编程报错:“syntax error near unexpected token `”
    undo表空间不足,ORA-30036: unable to extend segment by 8 in undo tablespace 'UNDOTBS2'
    HTML快速入门
    HTTP协议快速入门
    Java Web应用的开发模式
    使用Jekyll搭建免费的Github Pages个人博客
    前端模拟API数据的两种方式
    Node.js学习笔记
    socket.io笔记
  • 原文地址:https://www.cnblogs.com/watalo/p/12313580.html
Copyright © 2011-2022 走看看