zoukankan      html  css  js  c++  java
  • 继承和派生

    1. 继承

    1. 什么是继承

    • 继承:就是新建类的方法,新建的类称之为子类或者派生类,子类继承的类叫做父类,也称之为基类或超类。简单的说:一个类可以得到另一个类名称空间中的属性和方法的这个特性,这种特性就是通过继承来实现的

    • 继承的特征:

      子类可以继承父类的属性(特征和技能),并且可以派生出自己的属性(特征和技能)

    • 在python中,一个子类可以继承多个父类,其它编程语言只能一个子类继承一个父类(面试可能会问)

    2. 为什么要继承

    • 继承的目的就是为了减少代码冗余(减少重复代码)

    3. 怎么继承,如何实现继承

    1. 首先要确定好谁是子类谁是父类

    2. 在定义类时,子类 + () ,()内写父类的名字,实现子类继承父类

      #  子类B继承父类A
      class A:
          pass
      class B(A):
          pass
      
      print(B.__bases__) #查看B继承的父类们,以元组飞形式打印出各父类
      print(B.__bases__[0].__dict__) # 查看B的第一个父类的属性
      
    3. 什么是抽象?
      抽象指的是抽取相似的部分,称之为抽象.

    4. 继承的关系:
      对象是特征与技能的结合体.
      类是一系列对象相同的特征与技能的结合体.
      继承是一系列类相同的特征与技能的结合体.

    4. 继承后,对象的属性的搜索顺序

    • 下面的查找中,只要找到了就不会继续找了
    1. 先从对象的名称空间中查找该属性
    2. 若对象的名称空间中没有,就会去子类的名称空间中查找
    3. 若子类中没有,就去父类中查找,并且按照父类的继承顺序查找。

    5. 新式类和经典类(面试会问)

    • python2 中才会有新式类和经典类之分。
    • python3 中所有的类都是新式类

    1. 新式类

    • 什么是新式类:

      继承object的类都称之为新式类

      python3 中,子类如果不继承自定义的类,会默认继承object

    2. 经典类

    • 什么是经典类

      在python2 中,凡是没有继承object 的类都是经典类

    3. mro() / __class__ / __name__ 方法

    • mro()方法是属于object类中的方法,在多继承情况下,可以用来查看当前类的继承顺序。他返回的结果是一个元组。注意要索引取值。
    • __class__ 是对象的方法,可以获得实例化该对象的类。
    • __name__ 一种通用的方法,类/函数 通过.__name__可以获取类/函数的 名字。

    4. 钻石继承(也称为菱形继承)

    • 在多继承的情况下会形成钻石继承

    • 钻石继承的继承顺序:分为 新式类 和 经典类 的继承顺序

    (1) 新式类的钻石继承顺序

    • 新式类的钻石继承顺序为 : 广度优先。

    • 它的特点是按一个子类的继承时括号内的书写顺序,从左到右依次,(如子类1(A,D,G...)),先继承:

      第一个父类A——》A的父类B——》B的父类C——》。。。

      第二个父类D——》D的父类E——》E的父类F——》。。。

      。。。

      但最后继承顶层的父类,再继承object类

    (2) 经典类的钻石继承顺序

    • 经典类的钻石继承顺序为: 深度优先

    • 它的特点是按一个子类的继承时括号内的书写顺序,从左到右依次,(如子类1(A,D,G...)),先继承:

      第一个父类A——》A的父类B——》B的父类C——》。。。——》顶层的父类

      第二个父类D——》D的父类E——》E的父类F——》。。。——》顶层父类继承过了,到顶层的父类的最近的一个儿子类就结束继承。开始第三个父类,第三个父类也是同第二个父类一样的继承顺序。

      。。。

    2. 继承的实例

    • 通过继承实现修改json模块的数据类型

      import json
      from datetime import date, datetime
      
      print(json.JSONEncoder)
      print(datetime.today())  # 当前时间
      print(date.today())  # 当前日期
      
      # 开发者的角度: 直接转成str
      # dict1 = {
      #     'name': 'tank',
      #     'today': str(datetime.today()),
      #     'today2': str(date.today())
      # }
      #
      # res = json.dumps(dict1)
      # print(res)
      
      
      # isinstance:
      # python内置的函数,可以传两个参数,判断参数一是否式参数二的一个实例.
      
      *********************继承的使用***********************
      # 开源者的角度: 修改json源码
      class MyJson(json.JSONEncoder):
          def default(self, o):
      
              # 子类派生的功能
              # 判断o是否式datetime的一个实例
              if isinstance(o, datetime):
                  return o.strftime('%Y-%m-%d %X')
              elif isinstance(o, date):
                  return o.strftime('%Y-%m-%d')
              else:
                  # 继承父类的default方法的功能
                  return super().default(self, o)
      
      
      dict1 = {
          'name': 'tank',
          'today': datetime.today(),
          'today2': date.today()
      }
      
      res = json.dumps(dict1, cls=MyJson)  # cls=None,默认指向的是原json的JSONEncoder
      print(res)
      

    3. 派生

    1. 什么是派生

    • 派生指的是子类继承父类的属性,并且产生自己新的属性
    • 子类派生出新的属性,若与父类的属性相同,则以子类的为准。

    2. 子类派生出新的属性,并重用父类的属性

    问题:子类继承了父类的__init__属性,但还需要添加自己的一些新的属性

    解决方法:

    注意下面的两种方法不要混合使用

    • 方法一:

      直接通过 父类.__init__(self,要重用的属性) 来实现重用父类属性
      
      class OldboyPeople:
          def __init__(self, name, age, sex):
              self.name = name
              self.age = age
              self.sex = sex
      class OldboyTeacher(OldboyPeople):
          # 等级, 薪资
          def __init__(self, name, age, sex, level, sal):
              OldboyPeople.__init__(self, name, age, sex)
              self.level = level
              self.sal = sal
      
    • 方法二:(比方法一,少写了self)

      super是一个特殊的类,在子类中调用super()会得到一个特殊的对象,
              通过"."指向的是父类的名称空间.
          
      class OldboyPeople:
          def __init__(self, name, age, sex):
              self.name = name
              self.age = age
              self.sex = sex
      class OldboyTeacher(OldboyPeople):
          # 等级, 薪资
          def __init__(self, name, age, sex, level, sal):
              super().__init__(name, age, sex)
              self.level = level
              self.sal = sal
      
  • 相关阅读:
    从Github上将laravel项目拉到新开发环境
    Nginx-Primary script unknown的报错的解决方法
    CentOS 7 安装PHP7+Nginx+Mysql5.7开发环境
    程序员面试经常会被问到的12个问题
    IOC(控制反转)的理解
    用冒泡排序的方法将数组从小到大排列
    常用设计模式详解
    PHP常见面试题总结
    能够遍历一个文件夹下的所有文件和子文件夹的函数
    线特征---LineMatching原理(四)
  • 原文地址:https://www.cnblogs.com/Mcoming/p/11648315.html
Copyright © 2011-2022 走看看