zoukankan      html  css  js  c++  java
  • 继承与派生、组合、菱形继承、多态

                    一、继承与派生

        1.什么是继承

            继承是一种新建类的方式,新建的类称为子类,被继承的类称为父类

            继承的特性是:子类会遗传父亲的属性

            强调:继承是类与类之间的关系

        2.为什么用继承

            继承的好处就是可以减少代码的冗余

        3.如何用继承

            在python中支持一个类同时继承多个父类

            在python3中:

                如果一个类没有继承任何类,那默认继承object类

            在python2中:

                如果一个类没有继承任何类,不会继承object类

     

            新式类:

                单凡继承了object的类以及该类的子类,都是新式类

            经典类:

                没有继承object的类以及该类的子类,都是经典类

     

            在python3中都是新式类,只有在python2中才区别新式类与经典类

     

     

                class Parent1(object):

                    pass

     

                class Parent2(object):

                    pass

     

                class Sub1(Parent1,Parent2):

                    pass

     

                # print(Sub1.__bases__)

                print(Parent1.__bases__)

                print(Parent2.__bases__)

     

    二、继承的应用

            #派生:子类中新定义的属性,子类在使用时始终以自己的为准

            class OldboyPeople:

                school = 'oldboy'

                def __init__(self,name,age,sex):

                    self.name = name #tea1.name='egon'

                    self.age = age #tea1.age=18

                    self.sex = sex #tea1.sex='male'

     

     

            class OldboyStudent(OldboyPeople):

                def choose_course(self):

                    print('%s is choosing course' %self.name)

     

     

            class OldboyTeacher(OldboyPeople):

                #            tea1,'egon',18,'male',10

                def __init__(self,name,age,sex,level):

                    # self.name=name

                    # self.age=age

                    # self.sex=sex

                    OldboyPeople.__init__(self,name,age,sex) #指名道姓访问某一个类的函数

                    self.level=level

     

                def score(self,stu_obj,num):

                    print('%s is scoring' %self.name)

                    stu_obj.score=num

     

            stu1=OldboyStudent('耗哥',18,'male')

            tea1=OldboyTeacher('egon',18,'male',10)

     

            #对象查找属性的顺序:对象自己-》对象的类-》父类-》父类。。。

            # print(stu1.school)

            # print(tea1.school)

            # print(stu1.__dict__)

            # print(tea1.__dict__)

     

            tea1.score(stu1,99)

     

            print(stu1.__dict__)

     

     

            # 在子类派生出的新功能中重用父类功能的方式有两种:

            #1、指名道姓访问某一个类的函数:该方式与继承无关

     

     

     

            小练习:

                 class Foo:

                    def f1(self):

                        print('Foo.f1')

     

                    def f2(self):

                        print('Foo.f2')

                        self.f1()

     

                class Bar(Foo):

                    def f1(self):

                        print('Bar.f1')

     

                #对象查找属性的顺序:对象自己-》对象的类-》父类-》父类。。。

                obj=Bar()

                obj.f2()

                '''

                Foo.f2

                Bar.f1

                '''

     

     

    三、组合

    1.什么是组合

        组合就是一个类的对象具备某一个属性,该属性的值是指向另外一个类的对象

     

    2.为何用组合

        组合也是用来解决类与类之间代码冗余问题的

     

    3.如何用组合

            class Course:

                def __init__(self, name, period, price):

                    self.name = name

                    self.period = period

                    self.price = price

     

                def tell_info(self):

                    msg = '''

                    课程名:%s

                    课程周期:%s

                    课程价钱:%s

                    ''' % (self.name, self.period, self.price)

                    print(msg)

     

     

            class OldboyPeople:

                school = 'oldboy'

     

                def __init__(self, name, age, sex):

                    self.name = name

                    self.age = age

                    self.sex = sex

     

     

            class OldboyStudent(OldboyPeople):

                def __init__(self, name, age, sex,stu_id):

                    OldboyPeople.__init__(self, name, age, sex)

                    self.stu_id = stu_id

     

                def choose_course(self):

                    print('%s is choosing course' % self.name)

     

     

            class OldboyTeacher(OldboyPeople):

                def __init__(self, name, age, sex, level):

                    OldboyPeople.__init__(self, name, age, sex)

                    self.level = level

     

                def score(self, stu, num):

                    stu.score = num

                    print('老师[%s]为学生[%s]打分[%s]' % (self.name, stu.name, num))

     

            #创造课程

            python=Course('python全栈开发','5mons',3000)

            linux=Course('linux运维','5mons',800)

     

            #创造学生与老师

     

            stu1=OldboyStudent('猪哥',19,'male',1)

            tea1=OldboyTeacher('egon',18,'male',10)

     

     

            #将学生、老师与课程对象关联/组合

            stu1.course=python

            tea1.course=linux

     

            stu1.course.tell_info()

            tea1.course.tell_info()

     

            #定义一个学生类为了得到学生对象 , 定义一个课程类为了得到课程对象,刚开始两者没关系

            我让学生对象具备某一个属性,而这个属性的值来自另外一个类。stu1.course定位到课程类对象。

            stu1的课程属性是属于学生对象属性,这个属性来自另外一个类,就可以用stu1.course.可以用到左侧

            对象,类的所有东西

     

     

     

    四、菱形继承问题

            1.菱形继承:

                当一个子继承多个父类时,多个父类最终继承了同一个类,称之为菱形继承

     

            2.菱形继承的问题:

                python2区分经典类与新式类,如果子的继承是一个菱形,那么经典类与形式的区别为?

                    经典类下查找属性:深度优先查找

                    新式类下查找属性:广度优先查找

     

     

                class G(object):

                    # def test(self):

                    #     print('from G')

                    pass

     

                class E(G):

                    # def test(self):

                    #     print('from E')

                    pass

     

                class B(E):

                    # def test(self):

                    #     print('from B')

                    pass

     

                class F(G):

                    # def test(self):

                    #     print('from F')

                    pass

     

                class C(F):

                    # def test(self):

                    #     print('from C')

                    pass

     

                class D(G):

                    # def test(self):

                    #     print('from D')

                    pass

     

                class A(B,C,D):

                    def test(self):

                        print('from A')

                    # pass

     

                obj=A()

                print(A.mro())

                # obj.test() #A->B->E-C-F-D->G-object

     

                继承原理(C3算法与mro)继承原理 MRO列表就是一个简单的所有基类的线性顺序列表

     

     

     

     

     

     

     

     

    五、在子派生的新方法中重用父类功能的两种方式

     

        方式一:

                指名道姓法,直接用:类名.函数名

            class OldboyPeople:

                school = 'oldboy'

     

                def __init__(self, name, age, sex):

                    self.name = name

                    self.age = age

                    self.sex = sex

     

            class OldboyStudent(OldboyPeople):

                def __init__(self, name, age, sex, stu_id):

                    OldboyPeople.__init__(self, name, age, sex)

                    self.stu_id = stu_id

     

                def choose_course(self):

                    print('%s is choosing course' % self.name)

     

        方式二:

                严格依赖继承属性查找关系

            super()会得到一个特殊对象,该对象就是专门用来访问父类中的属性(按照继承关系)

            super().__init__(不用为self传值)

     

            注意:

            super的完整用法是super(自己的类名,self),在python2中需要写完整,而python3中可以写super()

            

            强调:二者使用哪一种都可以,但最好不要混合使用

                   

            lass OldboyPeople:

                school = 'oldboy'

            

                def __init__(self, name, age, sex):

                    self.name = name

                    self.age = age

                    self.sex = sex

            

            

            class OldboyStudent(OldboyPeople):

                def __init__(self, name, age, sex, stu_id):

                    super().__init__(name,age,sex)           ######

                    # OldboyPeople.__init__(self, name, age, sex)

                    self.stu_id = stu_id

            

                def choose_course(self):

                    print('%s is choosing course' % self.name)

            

            stu1=OldboyStudent('egon',19,'male',10)

            print(stu1.__dict__)

     

     

        小练习:

                    class A:

                        def f1(self):

                            print('A.f1')

                    

                    

                    class B:

                        def f2(self):

                            super().f1()

                            print('B.f2')

                    

                    

                    class C(B, A):

                        pass

                    

                    obj=C()

                    obj.f2()

                    

                    

                    print(C.mro())  # C->B->A->object   B没有继承A,但super会基于C.mro()继续往后找  

                                                         super严格依赖继承关系,从当前类的下一个类开始查找

                    # A.f1

                      B.f2

     

     

     

    六、多态与多态性

            1.什么是多态

                多态指的是同一种事物的多种状态

                水--》冰、水蒸气、液态水

                动物——》人、狗、猪

            2.为什么用多态

                多态性:继承同一个类的多个子类有相同的方法名

                那么子类产生的对象就可以不用考虑具体类型而直接调用功能

                

            3.如何用

                动物多态:

                import abc    #abc=abstract class

                

                class Animal(metaclass=abc.ABCMeta):

                    @abc.abstractmethod

                    def speak(self):

                        pass

                    @abc.abstractmethod

                    def eat(self):

                        pass

                

                # Animal() #强调:父类是用来指定标准的,不能被实例化

                

                class People(Animal):

                    def speak(self):

                        print('say hello')

                

                    def eat(self):

                        pass

                

                class Dog(Animal):

                    def speak(self):

                        print('汪汪汪')

                

                    def eat(self):

                        pass

                class Pig(Animal):

                    def speak(self):

                        print('哼哼哼')

                

                    def eat(self):

                        pass

      

     python推崇的是鸭子类型,只要你叫的声音像鸭子,并且你走路的样子也像鸭子,那你就是鸭子  

      

                

          

          多态性是指在不考虑实例类型情况下使用实例     

                class Disk:

                    def read(self):

                        print('disk read')

                

                    def write(self):

                        print('disk wirte')

                

                

                class Process:

                    def read(self):

                        print('process read')

                

                    def write(self):

                        print('process wirte')

                

                

                class File:

                    def read(self):

                        print('file read')

                

                    def write(self):

                        print('file wirte')

     

  • 相关阅读:
    js 中 && 和 ||
    The server time zone value 'EDT' is unrecognized or represents more than one time zone.
    docker进入容器
    docker 挂载本地目录
    Docker for Windows 挂载目录失败
    docker下redis启动 根据本地配置文件
    docker 安装 nacos/nacos-server 镜像并配置本地数据库
    spring cloud Nacos Config配置中心
    Docker卸载
    虚拟机centos添加硬盘和分区挂载
  • 原文地址:https://www.cnblogs.com/kingyanan/p/9235449.html
Copyright © 2011-2022 走看看