zoukankan      html  css  js  c++  java
  • python学习 day23 面向对象三大特性之继承

    ### 面向对象三大特性值继承
    #### 1.什么是继承
    继承是一种关系,必须存在两个对象才可能产生这种关系,在现实生活中的继承,王思聪可以继承王健林的财产
    被继承的成为父,继承的一方成为子

    在程序中,继承指的是类与类之间的关系

    #### 2.为什么要使用继承
    在生活中,通过继承 子可以直接享受父提供的内容,例如财产
    在程序中,通过继承可以直接使用父类已有的代码

    #### 3.怎么使用
    在子类中,类名后面加上括号,写上父类的名称即可
    在python中,一个子类,可以有多个父类,多个父类在括号中用逗号隔开,这一点在其他语言是不支持的
    # class Father:
    # pass
    # class GanDie:
    # pass
    # 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() # 子类也可以父类中的函数



    #### 4,继承与抽象

    学生继承了老师,减少了重复代码,但是继承到一些学生不应该有的内容
    正确方法:抽取公共的父类 抽象
    抽象是抽取相同的部分,形成另一个类
    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()



    # 通过继承,避免了重复代码的编写
    # 通过抽象,避免了继承到一些不应该有的内容
    # 应该先抽象后继承
    # 在抽象过程中,可能会有一些业务需求五关的类,这是正常的,这些类称之为公共父类
    # 公共父类的作用是存储多个子类相同的属性和技能


    #### 5.派生
    什么是派生
    派生是子类继承某个父类,并且拥有自己独特的属性或技能,该子类称之为派生类

    #只有子类中出现了新内容,它就是一个派生类


    #Student类就称为Person类的派生类

    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 正在上课.....")



    #### 6.子类访问父类中的方法

    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)
    super().sayHI()
    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)



    # super一定用在 存在继承关系的子类中

    在子类中重用父类的方式1:指名道姓的调用父类的方法,这样做就与继承没有关系

    方式2:
    super() # 表示创建一个特殊的对象,用于调用父类的方法
    super().__init__()

    了解:在python2中,super的使用方式有所不同,需要传入当前类,当前对象
    super(Student,self).__init__()

    访问父类中的方法来简化代码

    super() 一定是用在存在继承关系的子类中

    #### 7.存在继承关系后的属性查找


    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__)


    对象->类->父类->父类的父类....
    优先找对象,如果对象没有,则找类,如果类没有,会沿着继承关系一直找到最顶层的父类
    # 无论是属性还是方法,查找顺序是一样的

    继承了多个父类的情况

    1.按照继承的顺序 先继承先找谁
    深度优先,沿着一条继承路径找到底,如果没有再找其他继承路径
    这种查找方式,仅仅在没有非菱形继承

    #### 8.经典类和新式类 ***
    所有直接继承或间接继承object的类,都是新式类
    object称之为根类,所有类的都源自于object类
    为什么这么设计?
    例如:创建对象时,需要申请内存空间,创建新的名词空间,将对象的属性放入名称空间,这一系列负责的基础操作,都由object来完成
    简单地说object提供了一些常用的基础操作
    即所有类都属于新式类(在python3中)

    在python3中默认所有类都是新式类
    在python2中默认是经典类

    class S:
    pass
    class Student(S):
    pass

    # __bases__用于查看父类
    print(Student.__bases__)

    __bases__,用于查看父类
    内置属性__bases__

    在经典类中,属性的查找按照深度优先,一条路摸到黑,python2中才有经典类,先深度,再广度

    #### 9.菱形继承 ***
    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
    """

    当存在共同父类时,会产生菱形继承关系

    在菱形继承中,会先深度优先,再广度优先,该查找顺序是通过一个C3算法得来

    #### 10.mro ***
    # 显示属性的查找顺序列表,属性查找就是按照该列表来查找
    print(Student.mro())

    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()



    #### 11.覆盖

    class A:
    age = 18
    def f1(self):
    print(" A f1")
    pass
    class B(A):
    age1 = 19
    def f1(self):
    self.f1()
    print(" B f1")
    pass
    b1 = B()
    print(b1.age)

    b1.f1()

    子类中定义与父类同名属性,就是覆盖
    子类中定义与父类不同属性,就是继承


    ### 回顾
    1.什么是继承 一种关系
    2.为什么继承 减少重复代码 *****
    3.在子类的类名后面加括号,括号中写父类的名字,可以有多个父类
    4.先抽象,再继承 *****
    5.派生与覆盖 ***
    6.子类访问父类方法的两种方式
    1.指名道姓地调用
    2.使用super() 查找顺序按照mro列表
    7.存在继承后的属性查找顺序,mro列表

    8.经典类与新式类 python3中都是新式类

  • 相关阅读:
    Spring(八)-spring5框架新功能
    Spring(七)-事务操作
    Spring(五)-AOP
    Linux errno错误码
    思考:如何保证服务稳定性?
    CPU性能分析工具原理
    Oracle数据库url格式
    java对象的四种引用:强引用、软引用、弱引用和虚引用
    给老板汇报技术规划的要点
    后端程序员必备:分布式事务基础篇
  • 原文地址:https://www.cnblogs.com/shanau2/p/10120195.html
Copyright © 2011-2022 走看看