zoukankan      html  css  js  c++  java
  • 面向对象之继承

    面向对象三大特性之继承

    一.继承

    1.什么是继承

      继承是一种关系,必须存在两个对象才可能产生这一种关系。在程序中继承指的是类与类之间的关系。新建的类可以继承1个或者多个父类,父类又被称为基类,超类,新建的类可以被称为子类或派生类。

    2.为什么要使用继承

    在程序中,通过继承可以直接使用父类已有的代码,可以减少类与类之间的代码冗余。

    3.怎么使用继承

    #单继承
    class
    Father: #定义父类 a=10 class Son( 父类的名称 Father): #定义子类 pass son=Son() print(son.a) >>>: 10

    #多继承
    class Father1:  #定义父类
        a=10
    class Father2:  #定义父类
        b=10
    class Son( 父类的名称 Father1,Father2):#python支持多继承,用逗号分隔开多个继承的类

    son=Son()

    print(son.a)

    print(son.b)
    >>>:
    10
    10
     

    4.查看继承

    print(Son.__bases__) #使用__bases__可以查看Son类所继承的所有父类
    >>>:
    (<class '__main__.Father1'>, <class '__main__.Father2'>)

    二.继承与抽象(先抽象后继承)

    继承是类与类之间的一种关系,抽象是指抽取多个类中相同的部分形成一个类。

    抽象分成两个层次: 

    1.将奥巴马和梅西这俩对象比较像的部分抽取成类; 

    2.将人,猪,狗这三个类比较像的部分抽取成父类。

    抽象最主要的作用是划分类别(可以隔离关注点,降低复杂度)

    继承:是基于抽象的结果,通过编程语言去实现它,肯定是先经历抽象这个过程,才能通过继承的方式去表达出抽象的结构。

    三.派生

    1.什么是派生

    派生指的是子类继承某个父类,但是这个子类拥有自己独特的属性或者技能,那么该子类就称之为派生类,也就是说子类中出现了新内容那么他就是一个派生类。

    注意:派生类一定是子类,但是子类不一定是一个派生类。

    #普通子类
    class
    Person: def __init__(self,name,age,sex): self.name = name self.age = age self.sex = sex def sayHI(self): print("hello 我是%s 今年%s岁 性别:%s" % (self.name,self.age,self.sex)) class Test(Person): pass #此时Test不能被称为派生类,它只是一个子类,因为Test类没有任何独特的内容,它的内容与父类完全一致。
    #派生类
    
    class Student(Person):# class Test(Person):
    # pass

    def __init__(self,name,age,sex,number):
    self.name = name
    self.age = age
    self.sex = sex
    self.number = number

    # 上课
    def up_class(self):
    print("%s 正在上课.....")
    #此时Student类是一个派生类,因为它比父类Person多了一个方法和一个number属性

    在上述派生类的代码中,我们发现我们重新写了一个初始化函数将参数自动传进去,那么不就又回到了没有继承之前的写法了吗,有没有什么方法能让子类可以继续使用父类的特征,然后在添加一个可以自动传参的特征呢?下面我们就来介绍一些这个方法。

    四.子类访问父类的方法

    1.指名道姓的访问父类的方法

    class Person:
        def __init__(self,name,age,sex):
            self.name=name
            self.age=age
            self.sex=sex
    
    class Student(Person):
        def __init__(self,name,age,sex,number):
            Person.__init__(self,name,age,sex)
    
            self.number=number
    
    stu1=Student("egon",18,"man","007")
    print(stu1.name,stu1.age,stu1.sex,stu1.number)
    
    >>>:
    egon 18 man 007
    
    #看上面的代码,在子类的初始化函数中,直接调用父类名.__init__(self,.....)的形式能直接调用定义在父类中的初始化函数,从而达到了可以访问父类属性的目的。

    2.使用super()函数的方式访问父类

    class Person:
        def __init__(self,name,age,sex):
            self.name=name
            self.age=age
            self.sex=sex
    
    
    class Student(Person):
        def __init__(self,name,age,sex,number):
            super().__init__(name,age,sex)   
    
    
            #python2中的用法,但是python3也兼容这种形式
            # super(Student, self).__init__(name,age,sex) 
    
            self.number=number
    
    stu1=Student("egon",18,"man","007")
    print(stu1.name,stu1.age,stu1.sex,stu1.number)
    
    >>>:
    egon 18 man 007

    补充知识:super()函数对类中的方法也有相同的作用

    class Person:
        def __init__(self,name,age,sex):
            self.name=name
            self.age=age
            self.sex=sex
        def sayHi(self):
            print("BYE BYE")
    
    class Student(Person):
        def __init__(self,name,age,sex,number):
            super().__init__(name,age,sex)
            self.number=number
    
        def sayHi(self):
            super().sayHi()
            print("see you tomorrow")
    
    stu1=Student("egon",18,"man","007")
    stu1.sayHi()
    
    >>>:
    BYE BYE
    see you tomorrow
    
    #当我们需要在子类继承父类的方法中添加新东西中,可以使用super函数的方法添加
    super()为子类继承的父类方法添加功能

     五.继承关系下的属性查找问题   (子类出现了与父类重复的名字 称之为覆盖)

    由于一个子类可以继承多个父类,所以有可能会出现菱形继承的形式,所以继承关系下的属性查找也分为两类

    1.继承多父类的继承关系下的非菱形继承下的属性查找规则:深度优先

    class A(object):
        def test(self):
            print('from A')
    
    class B(A):
        def test(self):
            print('from B')
    
    class C(A):
        def test(self):
            print('from C')
    
    class D(B):
        def test(self):
            print('from D')
    
    class E(C):
        def test(self):
            print('from E')
    
    class F(D,E):
        # def test(self):
        #     print('from F')
        pass
    f1=F()
    f1.test()
    
    顺序为:F->D->B->E->C->A

    2.继承多个父类的继承关系下菱形继承下的属性查找规则:深度优先+广度优先

    class S:
        a = 100
    
    class A(S):
        # a = 1
        pass
    class B(S):
        # a = 2
        pass
    class C(S):
        # a = 3
        pass
    class D(A):
        # a = 4
        pass
    class E(B):
        # a = 5
        pass
    class F(C):
        # a = 6
        pass
    class G(D,E,F):
        pass
    
    
    g1 = G()
    print(g1.a)
    print(G.mro())
    
    """
    s
    a,b,c
    d,e,f
    g
    """
    g->d->a->e->b->f->c->s

    六.经典类与新式类

    1.只有在python2中才分新式类和经典类,python3中统一都是新式类
    2.在python2中,没有显式的继承object类的类,以及该类的子类,都是经典类
    3.在python2中,显式地声明继承object的类,以及该类的子类,都是新式类
    3.在python3中,无论是否继承object,都默认继承object,即python3中所有类均为新式类
    杜绝秃头!!!
  • 相关阅读:
    Lodash之throttle(节流)与debounce(防抖)总结
    css伪类:before及:after除了插入文字内容还能做点儿啥?画图
    一点对Promise的理解与总结
    前端开发常用网站汇总
    一分钟配置好JDK
    启动任务管理器命令符,doc命令
    判断是否是质数以及类型的转换
    图片数字型的九九乘法表
    1000以内的质数的方法,判断年份是否是闰年,打印水仙花数
    持续交付8-数据管理
  • 原文地址:https://www.cnblogs.com/846617819qq/p/10119784.html
Copyright © 2011-2022 走看看