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

    继承

    什么是继承

    继承指的是新建类的方法,新建的类称之为子类或派生类;

    子类继承的类为父类,也称之为基类或超类。

    继承的特征

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

    为什么要继承

    继承的目的是为了减少代码的冗余(减少代码量)

    如何实现继承

    1. 首先要确定谁是父类,谁是子类
    2. 在定义类时,子类+(),()内写父类,实现继承
    class 父:
        pass
    
    class 子(父):
    	pass
    
    class Parent1:
        pass
    
    class Parent2:
        pass
    
    
    class Sub1(Parent1):
        pass
    
    
    class Sub2(Parent1, Parent2):
        pass
    
    # 查看继承的父类: __bases__, 用来查找当前类的父类
    print(Sub1.__bases__)   # (<class '__main__.Parent1'>,)
    
    print(Sub2.__bases__)   # (<class '__main__.Parent1'>, <class '__main__.Parent2'>)
    

    注:一个子类可以继承多个父类,这是python独有的,其他语言只能一个子类继承一个父类

    继承与抽象

    如何寻找继承关系

    想要寻找继承关系,首先要先抽象,再继承

    抽象:抽象指的是抽取相似的地方

    • 先抽象(抽象思想)
      • 奥巴马 ---> 人类 ---> 动物类
      • 猪坚强 ---> 猪类 ---> 动物类
      • 阿黄 ---> 狗类 ---> 动物类
      • 抽象定义动物类,为父类
    • 再继承(程序中)
      • 奥巴马对象 ---> 调用人类 ---> 继承动物类
      • 猪坚强对象 ---> 调用猪类类 ---> 继承动物类
      • 阿黄对象 ---> 调用狗类 ---> 继承动物类

    继承的关系

    • 对象是特征与技能的结合体
    • 类是一系列相同对象的特征与技能的结合体
    • 继承是一系列形同类的特征与技能的结合体
    class People:
        school = 'oldboy'
    
        def __init__(self, name, age, sex):
            self.name = name
            self.age = age
            self.sex = sex
    
    
    class Teacher(People):
        def change_score(self):
            print(f'{self.name}老师正在该分数。。。')
    
    
    class Student(People):
        def choose_course(self):
            print(f'{self.name}同学正在选课。。。')
    
    
    tea1 = Teacher('tank', 18, 'male')
    stu1 = Student('小明', 18, 'male')
    
    tea1.change_score()
    stu1.choose_course()
    
    '''
    tank老师正在该分数。。。
    小明同学正在选课。。。
    '''
    

    对象属性的查找顺序

    1. 对象查找属性会先从对象的名称空间中查找。
    2. 若对象没有,则从类中查找
    3. 若当前类是子类,并且没有对象找的属性,就去父类中查找
    4. 若父类中也没有机会报错

    注:对象查找属性,若子类有,不管父类有没有,以子类的为准

    验证查找顺序:

    class Foo:
        def f1(self):
            print('Foo.f1')
    
    
    
        def f2(self):
            print('Foo.f2')
            self.f1()
    
    
    class Soo(Foo):
        def f1(self):
            print('Soo.f1')
    
    
    soo_obj = Soo()
    soo_obj.f2()
    '''
    Foo.f2
    Soo.f1
    '''
    

    首先soo_obj从对象自身找,没有去子类Soo中找,没找到,再去父类Foo中找,找到了打印'Foo.f2',接着就是self.f1(),self就是对象本身,按照对象---> 子类--->父类的顺序找,再子类Soo中找到了打印'Soo.f1'

    派生

    派生指的是子类继承父类的属性,并且派生出新的属性。

    子类派生出新的属性,若与父类的属性相同,则以子类的为准。

    继承是谁与数的关系,指的是类与类的关系,子类与父类是从属关系

    派生方法一(类调用)

    直接通过父类.__init__,把__init__当作普通函数使用。

    class People:
        def __init__(self, name, age, sex):
            self.name = name
            self.age = age
            self.sex = sex
    
    class Teacher(People):
        def __init__(self, name, age, sex, level, salary):
            People.__init__(self, name, age, sex)
            self.level = level
            self.salary = salary
    
    
    class Student(People):
        def __init__(self, name, age, sex, course):
            People.__init__(self, name, age, sex)
            self.course = course
    
        def choose_course(self):
            print(f'{self.name} is choosing {self.course}')
    
    
    tea1 = Teacher('tank', 18, 'male', 9, '3.0')
    stu1 = Student('小明', 18, 'male', 'python')
    stu1.choose_course()
    
    '''
    小明 is choosing python
    '''
    

    派生方法二(super)

    • super是一个特殊的类,在子类中调用super()会得到一个特殊的对象,通过"."指向父类的名称空间
    • super().__init__(不用为self传值)
    class People:
        def __init__(self, name, age, sex):
            self.name = name
            self.age = age
            self.sex = sex
    
    class Teacher(People):
        def __init__(self, name, age, sex, level, salary):
            super().__init__(name, age, sex)
            self.level = level
            self.salary = salary
    
    
    class Student(People):
        def __init__(self, name, age, sex, course):
            super().__init__(name, age, sex)
            self.course = course
    
        def choose_course(self):
            print(f'{self.name} is choosing {self.course}')
    
    
    tea1 = Teacher('tank', 18, 'male', 9, '3.0')
    stu1 = Student('小明', 18, 'male', 'python')
    stu1.choose_course()
    

    新式类与经典类

    • 在python2中,才会有新式类与经典类之分
    • 在python3中,所有的类都是新式类

    新式类

    • 继承object的类都是新式类
    • python3中,子类不继承自定义的类,默认继承object

    经典类

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

    mro查看继承顺序

    mro(): 是python内置的函数,用来查看当前类的继承顺序,在多继承的情况下

    class A:
        pass
    
    class B:
        pass
    
    class C(A, B):
        pass
    
    print(C.mro())  
    
    # [<class '__main__.C'>, <class '__main__.A'>, <class '__main__.B'>, <class 'object'>]
    

    钻石继承(菱形继承)

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

    • 经典类: 深度优先
    • 新式类: 广度优先

    修改json数据格式

    import json
    from datetime import datetime
    from datetime import date
    
    dic = {
        'name': 'tank',
        'today1': date.today(),
        'today2': datetime.today()
    }
    
    class MyJson(json.JSONEncoder):
        def default(self, o):
            # 判断o是否是datetime的一个实例
            if isinstance(o, datetime):   # instance 是python内置的函数,可以传两个参数,判断参数一是否是参数二的一个实例
                return o.strftime('%Y-%m-%d %X')
            elif isinstance(o, date):
                return o.strftime('%Y-%m-%d %X')
            else:
                # 继承父类default方法的功能
                return super().default(self, o)
    
    res = json.dumps(dic, cls=MyJson)  # cls=None, 默认指向的是原json的JSONEncoder
    print(res)
    '''
    {"name": "tank", "today1": "2019-10-10 00:00:00", "today2": "2019-10-10 17:00:20"}
    '''
    
  • 相关阅读:
    ThinkJava-复用类
    ThinkJava-访问权限控制
    ElasticSearch 5.0及head插件安装
    安装Elasticsearch5.0 部署Head插件
    Elasticsearch 5.1.1 head插件安装指南
    使用logstash+elasticsearch+kibana快速搭建日志平台
    logstash使用操作部分
    ELK 集中日志分析 windows部署实战
    关于异步,同步,阻塞与非阻塞
    Zookeeper的集群配置和Java测试程序
  • 原文地址:https://www.cnblogs.com/setcreed/p/11650266.html
Copyright © 2011-2022 走看看