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

    一.继承基础

    1.什么是继承?

    继承指的是一种关系,它必须存在两个对象,才会发生继承这件事。在程序中,继承指的是类与类之间的关系。被继承的称为父,继承的称为子。

    2.为什么要使用继承?

    在程序中,通过继承可以直接使用父类已有的代码,从而简化代码。

    3.如何使用继承?

    语法:在子类中,类名后面加括号,括号里写上父类的名称即可,可以是多个,用逗号分隔开。

    子类可以使用父类中的属性,也可以使用父类中的函数。

    # class Father:
    #     pass
    #
    #
    # class GanDie:
    #     pass
    #
    # # 在子类中 类名后面加上括号,些上父类的名称即可,
    # # 在python中一个子类可以有多个父类,多个父类在括号中用逗号隔开,,这一点在其他语言中是不支持的
    # class Son(Father,GanDie):
    #     pass
    
    
    
    class Parent:
        year = 2018
    
        def coding(self):
            print("正在编程........")
    
    
    
    class Sub(Parent):
        pass
    
    print(Parent.year)
    
    print(Sub.year)
    
    # Sub.coding()
    
    
    s = Sub()
    print(s.year) # 子类可以使用父类中的属性
    s.coding() # 子类也可以父类中的函数
    继承的使用

    子类继承父类之后会出现一个问题,就是子类可能会继承到一些不应该有的属性,这就需要用到抽象的概念。

    抽象指的是抽取多个类中相同的部分形成另一个类。这样就可以避免继承到一些不应该有的内容,在抽取的过程中,也可能会产生一些跟业务需求无关的类,但是并不影响。

    class Person:
        def __init__(self ,name ,age ,sex):
            self.name = name
            self.age = age
            self.sex = sex
    
        def eat(self):
            print("正在吃饭....")
    
        def study(self):
            print("正在学习....")
    
    class Teacher(Person):
    
        def teaching(self):
            print("老师正在上课......")
    
    t1 = Teacher("blex" ,30 ,"woman")
    t1.eat()
    t1.study()
    
    
    class Student(Person):
        pass
    
    stu1 = Student("张三" ,20 ,"man")
    stu1.eat()
    stu1.study()
    抽象

    二.派生与覆盖

    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))
    
    
    # Test不能称为派生类 , 因为没与任何独特的内容与父类完全一致
    class Test(Person):
        pass
    
    # 派生类属于子类吗?   派生类一定是某个子类
    # Student类就成为 Person类的派生类
    
    
    class Student(Person):
        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 正在上课.....")
    派生

    2.什么是覆盖?

    在子类中,如果存在与父类相同的属性名称时,优先使用子类中的属性,这种行为称之为覆盖。

    三.子类访问父类的方法

    简单的来说有两种方法:

    1.指名道姓的访问(父类名点语法)

    2.用super()函数访问(super()点语法)。该函数一定是用在存在继承关系的子类中的。在python2中用法:super(子类名,self)点语法。

    class Person:
        def __init__(self,name,age,sex):
            self.name = name
            self.age = age
            self.sex = sex
            print(self)
    
        def sayHI(self):
            print("hello 我是%s 今年%s岁 性别:%s" % (self.name,self.age,self.sex))
    
    
    class Student(Person):
        def __init__(self,name,age,sex,number):
            # self.name = name
            # self.age = age
            # self.sex = sex
            #上述代码与父类中完全相同
            Person.__init__(self,name,age,sex)
            self.number = number
        # 上课
        def up_class(self):
            print("%s 正在上课.....")
    
        def sayHI(self):
            # print("hello 我是%s 今年%s岁 性别:%s" % (self.name,self.age,self.sex))
            # 访问父类中的方法来简化代码
            # 指名道姓
            Person.sayHI(self)
            
            print("学号:",self.number)
    
    stu1 = Student("阿三",20,"woman","9527")
    # print(stu1)
    # print(stu1.name,stu1.age,stu1.sex)
    stu1.sayHI()
    方法一
    class Person:
        def __init__(self,name,age,sex):
            self.name = name
            self.age = age
            self.sex = sex
            print(self)
    
        def sayHI(self):
            print("hello 我是%s 今年%s岁 性别:%s" % (self.name,self.age,self.sex))
    
    class Student(Person):
        def __init__(self,name,age,sex,number):
            # self.name = name
            # self.age = age
            # self.sex = sex
            # 子类中重用父类种方法的方式2
            # super() # 表示创建一个特殊的对象 用于调用父类的方法
            # super().__init__(name,age,sex)
            # 了解:在python2中 super的使用方式有所不同 需要传入当前类,当前对象
            super(Student,self).__init__(name,age,sex)
            self.number = number
    
        # 上课
        def up_class(self):
            print("%s 正在上课.....")
    
    stu1 = Student("阿三",20,"woman","9527")
    print(stu1)
    print(stu1.name,stu1.age,stu1.sex)
    方法二

    四.继承的属性查找顺序

    查找顺序:对象---》类---》父类---》父类的父类......

    优先查找对象,如果不存在,则找类,如果类中不存在,则会沿着继承关系一直找到最顶层的父类。方法的查找顺序也是一样。

    class S:
        age = 17
    
        def f1(self):
            print("S f1")
    
    class A(S):
        # age = 18
        # def f1(self):
        #     print("A f1")
        pass
    class B(A):
        # age = 19
        # def f1(self):
        #     print("B f1")
        pass
    b = B()
    # b.age = 20
    
    print(b.age)
    
    print(b.__dict__)
    print(B.__dict__)
    print(A.__dict__)
    
    # 对象 -> 类 ->父类 ->父类的父类.....
    # 优先找对象 如歌对象没有 则找类,如果类没有,会沿着继承关系一直找到最顶层的父类
    # 无论是属性还是方法 查找顺序是一样的
    b2 = B()
    b2.f1()
    基本查找顺序

    如果继承关系为菱形结构,那么属性的查找方式有两种,分别是:深度优先和广度优先

    # class E:
    #     a = 5
    #
    # class A(E):
    #     a = 4
    #     pass
    #
    # class B:
    #     a = 3
    #     pass
    #
    # class C:
    #     a = 2
    #     pass
    #
    # class D(A,B,C):
    #     # a = 1
    #     pass
    #
    # d1 = D()
    # # d1.a = 10
    # print(d1.a)
    
    # 1.按照继承的顺序 先继承谁就先找谁
    
    
    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
    """
    菱形继承的属性查找

    五.经典类与新式类

    新式类:所有直接或间接继承object的类都是新式类。object称之为根类,即所有的类都源自于object类。(创建对象时,需要申请内存空间,创建新的名称空间,将对象的属性放入名称空间,这一些了复杂的基础操作,都有object来完成。简单地说:object提供了一些常用的基础操作。)

    在python3中默认所有类都是新式类,在python2中默认是经典类(不会自动继承object)。

    __bases__用于查看父类,mro()方法是一个列表,存放的是属性的查找顺序,这个mro()是通过c3线性算法得来。

    "super访问父类内容时 按照mro列表属性查找"
    
    class S:
        def f1(self):
            print("s f1")
    
    class A(S):
        pass
    
    class B(S):
        def f1(self):
            print("b f1")
        pass
    
    class C(A,B):
        def f2(self):
            print("c f2")
            super().f1()
    
    
    print(C.mro())
    c1 = C()
    c1.f2()
    
    class S:
        pass
    class Student(S):
        pass
    
    # __bases__用于查看父类
    print(Student.__bases__)
    
    # 显示属性的查找顺序列表,属性查找属性就是按照该列表来查找的
    print(Student.mro())
    View Code
  • 相关阅读:
    hdu 2444 交叉染色判断二分图+二分最大匹配
    uva 交叉染色法10004
    poj 3177&&3352 求边双联通分量,先求桥,然后求分量( 临界表代码)
    poj 3177&&poj 3352加边构双联通(有重边)用tarjan 模板求的
    poj 3006水题打素数表
    POJ 3352 无向图边双连通分量,缩点,无重边
    hdu 1430 魔板 康托展开 + 很好的映射
    D. Artsem and Saunders 数学题
    vijos P1412多人背包 DP的前k优解
    1475 建设国家 DP
  • 原文地址:https://www.cnblogs.com/wangke0917/p/10119639.html
Copyright © 2011-2022 走看看