• 继承初体验,寻找继承关系,继承背景下和对象属性查找顺序,派生,(子类派生出新的属性,并重新父类的属性),新式类与经典类,钻石继承。钻石继承实现修改jison模块数据类型。


    面向对象阶段最重要的知识点:

    ​ #### 面向对象的三大特征:

    ​ 1.继承

    ​ 2.封装

    ​ 3.多态

    继承:

    1.什么是继承?

    ​ 继承指的是新建类的方法, 新建的类称之为子类或者派生类,
    ​ 子类继承的类叫做父类,也称之为基类或超类.

    继承的特征:
        子类可以继承父类的属性(特征与技能), 并且可以派生出自己的属性(特征与技能).
    
    ******(面试问)
    注意: 在python中,一个子类可以继承多个父类,其他语言只能一个子类继承一个父类.
    

    2.为什么要继承?

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

    3.如何实现继承?

    ​ 1.首先要确定好谁是子类,谁是父类.
    ​ 2.在定义类时, 子类 + (), ()内写父类,实现继承.

    class 父:
        xxx = 111
        pass
    
    class 子(父):
        pass
    

    1.继承初体验

    class ParentClass1:
    	pass
    class PaerntClass2:
        pass
    
    # 子类
    class SubClass(PaerntClass2)
    # 继承多个父类
    class SubClass2(ParentClass1, ParentClass2):
        pass
    
    # 查看继承的父类: __bases__,是类的属性,用来查找当前类的父类.
    print(SubClass1.__bases__)  # (<class '__main__.ParentClass1'>,)
    print(SubClass2.__bases__)  # (<class '__main__.ParentClass1'>, <class '__main__.ParentClass2'>)
    
    

    2.寻找继承关系

    一如何寻找继承关系:

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

    什么是抽象?

    抽象就是抽取相似的部分,称之为抽象。

    - 先抽象(抽象思想):
        奥巴马 ---> 人类 ---> 动物类
        麦兜 ---> 猪类 ---> 动物类
        小丁丁 ---> 狗类 ---> 动物类
    
        抽象定义动物类,称之为父类.
            特征:
                眼睛,鼻子...
            技能:
                吃,喝,撒...
    
    - 再继承(在程序中):
        奥马巴对象 ---> 调用人类 ---> 继承动物类
        麦兜对象 ---> 调用猪类 ---> 继承动物类
        小丁丁对象 ---> 调用狗类 ---> 继承动物类
    
    继承的关系:
        对象是特征与技能的结合体.
        类是一系列对象相同的特征与技能的结合体.
        继承是一系列类相同的特征与技能的结合体.
    '''
    

    代码演示

    # 不继承情况下:
    # # 老师类: 名字,年龄,性别
    # class OldboyTeacher:
    #     school = 'oldboy'
    #
    #     def __init__(self, name, age, sex):
    #         self.name = name
    #         self.age = age
    #         self.sex = sex
    #
    #     # 老师修改分数技能
    #     def change_score(self):
    #         print(f'老师[{self.name} 修改分数...]')
    #
    #
    # # 学生类:  名字,年龄,性别
    # class OldboyStudent:
    #     school = 'oldboy'
    #
    #     def __init__(self, name, age, sex):
    #         self.name = name
    #         self.age = age
    #         self.sex = sex
    #
    #     # 学生可以选择课程
    #     def choose_course(self, course):
    #         print(f'学生[{self.name}]选择课程[{course}]')
    
    
    # 父类:
    '''
    抽象:
        school
        __init__(self, name, age, sex)
    '''
    class OldboyPeople:
        school = 'oldboy'
    
        def __init__(self, name, age, sex):
            self.name = name
            self.age = age
            self.sex = sex
    
    # 老师类: 名字,年龄,性别
    class OldboyTeacher(OldboyPeople):
        # 老师修改分数技能
        def change_score(self):
            print(f'老师[{self.name} 修改分数...]')
    
    # 学生类:  名字,年龄,性别
    class OldboyStudent(OldboyPeople):
    
        # 学生可以选择课程
        def choose_course(self, course):
            print(f'学生[{self.name}]选择课程[{course}]')
    
    stu1 = OldboyStudent('小丁丁', 95, 'female')
    tea1 = OldboyTeacher('tank', 17, 'male')
    
    print(stu1.name, stu1.age, stu1.sex)
    print(tea1.name, tea1.age, tea1.sex)
    
    

    3.继承背景下,对象属性查找顺序

    在继承背景下,对象属性的查找顺序: 
    1.对象查找属性会先从对象的名称空间中查找.   
    2.若对象没有,则会去类里面找.   
    3.若当前类是子类,并且没有对象找的属性,会去父类中查找    
    注意: 对象查找属性,若子类有,不管父类有没有,以子类的为准.
    
    # 验证对象属性的查找顺序
    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
    '''
    

    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.f1()  # Soo.f1  若与父类的属性相同,则以子类的为准
    
    

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

    问题: 子类继承父类的__init__毫无意义. 不能添加属性,添加则报错用不了
        列:
    
        
    
    解决方式有两种:   
    方式一:        直接通过 父类.(调用)__init__,把__init__当做普通函数使用,传入对象与继承的属性.       
    方式二:        super是一个特殊的类,在子类中调用super()会得到一个特殊的对象,        通过"."指向的是父类的名称空间.
       
    注意:两种方式不要混合使用。
    
    方法一:
    # class OldboyPeoPle:
    #     def __init__(self,name,age,sex):
    #         self.name = name
    #         self.sge = 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
    # 
    # class OldboyStudent(OldboyPeoPle):
    #     def  __init__(self,name,age,sex,course):
    #         OldboyPeoPle.__init__(self,name,age,sex)
    #         self.course = course
    # 
    #     def choose_course(self):
    #         print(f'学生{self.name}选择课程{self.course}')
    # 
    # tea1 = OldboyTeacher('tank',18,'male',9,'3.0')
    # stu1 = OldboyStudent('小丁丁',20,'female','python')
    # print(tea1.name,tea1.level)  #tank 9
    # print(stu1.name,stu1.course) #小丁丁 python
    # stu1.choose_course()  #学生小丁丁选择课程python
    
    方法二:
    class OldboyTeacher(OldboyPeople):
        # 等级, 薪资
        def __init__(self, name, age, sex, level, sal):
            super().__init__(name, age, sex)
            self.level = level
            self.sal = sal
    
    
    class OldboyStudent(OldboyPeople):
        # 课程
        def __init__(self, name, age, sex, course):
            super().__init__(name, age, sex)
            self.course = course
    
        def choose_course(self):
            print(f'学生{self.name}选择课程{self.course}')
    
    
    # print(super)
    tea1 = OldboyTeacher('tank', 17, 'male', 9, '3.0')
    stu1 = OldboyStudent('小健健', 20, 'female', 'python')
    print(tea1.name, tea1.level)
    print(stu1.name, stu1.course)
    stu1.choose_course()
    

    6.新式类与经典类

    新式类与经典类(了解):(面试)

    在python2中,才会有新式类与经典类之分.
        在python3中,所有的类都是新式类.
    
        新式类:
            继承object的类都称之为新式类.
            python3中,子类不继承自定义的类,默认继承object.
    
        经典类:
            在python2中,凡是没有继承object的类都是经典类.
    
    # 在python3:
    # 新式类:
    # class Foo(object):
    #     pass
    # class Goo(Foo):
    #     pass
    # # print(Foo.__bases__)  # (<class 'object'>,)
    # print(Goo.__bases__)  # (<class 'object'>,)
    

    7.钻石继承

    钻石继承也可以称之为菱形继承(了解)面试可能会问。

    ​ 再多集成的情况下形成的钻石继承(继承顺序)

    经典类:

    ​ 深度优先:

    ![](C:UsersDELLPicturesSaved PicturesQQ图片20191010153607.png)

    新式类:

    ​ 广度优先:

    ![](C:UsersDELLPicturesSaved PicturesQQ图片20191010153616.png)

    # 验证
    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 F(D,E):
        # def test(self):
        #     print('from F')
        pass
    
    
    # 新式类: F-D-B-E-C-A-object  #一级一级的查找
    f1 = F()
    f1.test()
    
    # 经典类: F-D-B-A-E-C
    
    
    

    ![](C:UsersDELLPicturesSaved PicturesQQ图片20191010153625.png)

    8.钻石继承实现修改jison模块数据类型

    import json
    from datetime import date,datetime
    print(json.JSONEncoder)
    print(datetime.today())# 当前时间
    print(date.today())  #当前日期
    

    python内置函数,可以传两个参数,判断参数一是否式参数二的一个实例

    # 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)
    
    
  • 相关阅读:
    博客园——程序员
    PHP获取IP
    VIM使用笔记
    再见,帕金!
    A Song of My Heart
    读书...
    纪念日...
    一路向北
    韬光养晦,希望能有所作为
    一首好歌!
  • 原文地址:https://www.cnblogs.com/WQ577098649/p/11650752.html
Copyright © 2020-2023  润新知