zoukankan      html  css  js  c++  java
  • python --- 面向对象

     """

    写在前面

    大型工程往往需要很多人合作开发,比如在 Facebook 中,在 idea 提出之后,开发组和产品组首先会召开产品设计会,

    PM(Product Manager,产品经理) 写出产品需求文档,然后迭代;

    TL(Team Leader,项目经理)编写开发文档,开发文档中会定义不同模块的大致功能和接口、每个模块之间如何协作、单元测试和集成测试、线上灰度测试、监测和日志等等一系列开发流程。

    """

    构造函数:创建对象时被自动调用

      def __init__(self, name ,age):

        self.name = name

        self.age = age

    私有属性 : 以两个下划线 开头  ,比如 __name  = '李刚' ,这里的__name 就是私有属性, 不可以在类的函数之外被访问(会报错,没有该属性)

          Python并没有真正的私有化支持,但可用下划线得到伪私有:
        (1)_xxx "单下划线 " 开始的成员变量 :叫做保护变量,意思是只有类对象和子类对象自己能访问到这些变量,需通过类提供的接口进行访问; 相当于java中 protected
        (2)__xxx “双下划线” :类中的私有变量/方法名,只有类对象自己能访问,子类对象也不能访问到这个数据。  相当于java中 private
        (3)__xxx__ 前后均有一个“双下划线”:魔法函数,代表python里特殊方法专用的标识,如 __init__() 代表类的构造函数。

         子类不能继承父类私有属性,只可透过self._Parent__varname去读取该私有属性的值, ;或者父类通过函数暴露其私有属性, 子类提供过父类对象调用该函数获取

    常量 :  在类中,与函数并列声明并赋值 , 常用做法是 用全大写的名字 , 可以通过对象调用,也可以通过类名称调用

    类函数(装饰器 @classmethod):持有类的引用,可以访问和修改类的属性

                  最常用的作用是 实现类不同的构造函数(重载)

    成员函数: 持有当前对象的引用,可以访问和修改对象的属性

    静态函数(装饰器 @staticmethod): 与类本身没有关联,不持有类的对象引用。  承担一些简单、独立的任务。 使用了装饰器的概念。

    抽象函数(装饰器 @abstractmethod): 在抽象类中定义,只定义函数名称 ,不提供任何实现

          @abstractmethod

          def abstract_method_demo(self,parameter,...):

            pass

    包含抽象函数的类 叫  抽象类,不允许直接调用生成对象, 否则会报错


    继承:

      # 父类

      class  Document():

        def __init__(self,obj_type):

          self.obj_type = obj_type

          print("初始化Document类")

        def get_context_length(self):

          raise Exception("get_context_length 方法还没有实现")

        def print_title(self):

          print(self.title)

      #子类 Book

      class Book(Document):

        def __init__(self,title,author,context):

          print("Book 类初始化")

          Document.__init__(self,'document')  # 调用父类的构造器,将本类对象 和 相关参数传递给父类

          self.title = title

          self.autor = author

          self.context = context

        def get_context_length(self):

          return len(self.context)

      # 子类 Video

      class Video(Document):

        def __init__(self,title,author,video_length):

          print("初始化Video类")

          Document.__init__(self,'video')

          self.title = title

          self.author = autuor

          self.video_length = video_length

        def get_context_length(self):

          return self.video_length

    Document(文档)类 是  Book 、 Video的父类

    第一,构造函数:  每个类都有构造函数,子类不会自动调用父类构造函数,必须在__init__() 构造器中 通过父类名.__init__(self,...) 显示调用其构造函数。 执行顺序  子类的构造函数 ---> 父类的构造函数

    第二,函数重写: 子类重写一遍父类的函数,实现自己的代码逻辑,覆盖掉父类的该函数

    多继承:

    菱形继承:

      比如,A 为基类, B继承A , C 继承A  , 然后D继承A、B 。

      潜在问题:一个基类的初始化函数可能被调用两次。比如上例,在D初始化过程中,可能会引起A类被调用两次

      解决办法:在子类中 用 super().__init__() 的方式来调用基类, 就可以避免菱形继承的问题了

      Python3.x 和 Python2.x 的一个区别是: Python 3 可以使用直接使用 super().xxx 代替 super(ParentClassName, self).xxx

      super().__init__() 只能调用第一个父类的构造函数,但对于多重继承,如果你想调用其他父类的构造函数,则必须指定。

     class A():
        def __init__(self):
            print('enter A')
            print('leave A')

    class B(A):
        def __init__(self):
            print('enter B')
            super().__init__()
            print('leave B')

    class C(A):
        def __init__(self):
            print('enter C')
            super().__init__()
            print('leave C')

    class D(B, C):
        def __init__(self):
            print('enter D')
            super().__init__()
            print('leave D')

    D()

    enter D
    enter B
    enter C
    enter A
    leave A
    leave C
    leave B
    leave D

    python3 使用一种叫做方法解析顺序的算法(mro算法),具体实现叫做 C3,来保证一个类只会被初始化一次。

    class A:
        # def test(self):
        # print('from A')
        pass
    class B(A):
        # def test(self):
        # print('from B')
        pass
    class C(A):
        # def test(self):
        # print('from C')
        pass

    class D(B):
        # def test(self):
        # print('from D')
        pass

    class E(C):
        # def test(self):
        # print('from E')
        pass

    class H(A):
        def test(self):
            print('from H')
        pass
    class F(D,E,H):
        # def test(self):
        # print('from F')
        pass
    f=F()
    f.test()
    print(F.mro())

    结果 : [<class '__main__.F'>, <class '__main__.D'>, <class '__main__.B'>, <class '__main__.E'>, <class '__main__.C'>, <class '__main__.H'>, <class '__main__.A'>, <class 'object'>]

    question: 面向对象的4要素

    封装,继承,多态,抽象
    封装:使得代码更加模块化,代码复用度更高
    继承:使得子类不仅拥有自己的属性和方法,还能使用父类的属性和方法
    多态:可以实现函数重写,使得相同方法具有不同功能
    抽象:不同子类的相同方法和属性形成父类,在通过继承,多态,封装使得代码更加紧凑,简洁易读

     在子类中调用已经被覆盖的父类方法,可以用 super(子类名称,self).父类方法

    调用父类方法:https://python3-cookbook.readthedocs.io/zh_CN/latest/c08/p07_calling_method_on_parent_class.html

      

      

          

  • 相关阅读:
    Sendkeys 和 Sendmessage 使用技巧一例
    和菜鸟一起学算法之二分法求极值问题
    和菜鸟一起学算法之三分法求极值问题
    和菜鸟一起学证券投资之国内生产总值GDP
    和菜鸟一起学OK6410之Led字符驱动
    和菜鸟一起学OK6410之最简单驱动模块hello world
    和菜鸟一起学OK6410之交叉编译hello world
    和菜鸟一起学android4.0.3源码之touchscreen配置+调试记录
    和菜鸟一起学android4.0.3源码之红外遥控器适配
    和菜鸟一起学OK6410之最简单字符驱动
  • 原文地址:https://www.cnblogs.com/wl413911/p/12983825.html
Copyright © 2011-2022 走看看