【0827 | Day 24】继承

继承介绍

一、什么是继承

继承是一种新建类的方式,继承了一个类,类中的属性和方法就在子类中。

  1. 父类/基类

  2. 子类/派生类

  3. 新式类:只要继承了object类,就是新式类,再python3中,默认继承object类

    • Python3中:默认继承object

      • class A:

        ​ pass

    • python2中,需要显示的指定继承object

  4. 经典类:没有继承object的类,就是经典类
    • python3中没有经典类
    • python2中才有

如何使用继承

class 类名(父类1, 父类2):
    pass

class A(object):
    pass

class C:
    pass

#B继承了A, C这个类
class B(A,C):
    pass


#类的其他内置方法
print(B.__dict__)

#类名
print(B.__name__)

#B的父类
print(B.__bases__)

减少代码冗余

#利用父类Person减少代码冗余
class Person:
    school = 'oldboy'

class Teacher(Person):
    def __init__(self,name,age,level):
        self.name = name
        self.age = age
        self.level = level

class Student(Person):
    def __init__(self,name,age,course):
        self.name = name
        self.age = age
        self.course = course

stu1 = Student('nick', 18, python)
print(stu1.school)  #oldboy

一、关于查找顺序

对象 ——> 类 ——> 父类 ——> 报错

class Person:
    school = 'oldboy' #1

class Teacher(Person):
    def __init__(self,name,age,level):
        self.name = name
        self.age = age
        self.level = level

class Student(Person):
    #school = 'oldbaby'  #3
    def __init__(self,name,age,course):
        self.name = name
        self.age = age
        self.course = course
        
stu1.school = 'oldgirl' #2
print(stu1.school)

#1 结果:oldboy
#2 结果:oldgirl
#3 结果:oldbaby

二、如何重用父类属性

class Person(object):
    school = 'oldboy'

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


class Teacher(Person):
    pass


class Student(Person):
    pass

stu1 = Student('nick', '18')

print(stu1.school)  #oldboy

三、多层继承

class A:
    a = "AAA"

class B(A):
    a = "BBB" #3

class C(B):
    a = "CCC" #2
    pass

class D(C):
    a = "DDD" #1
    pass


d=D()
print(d.a)

#1 结果:CCC
#2 结果:BBB
#3 结果:AAA

四、多继承

class A:
    a = "AAA"
    pass

class B:
    a = "BBB"
    pass

class C:
    a = "CCC"
    pass

class D(A,B,C):
    a = "DDD"
    pass

d = D()
print(d.a)

注意:多继承执行顺序,例D(A, B, C)是从左到右。

五、继承的菱形问题

img

img

总结:经典类(深度优先),第一支找到就不再查找;新式类(广度优先),最后一支找到为止。

六、mro列表

#mro 列表,继承顺序查找列表(只在新式类中有)
print(A.mro())
print(A.__mro__)

#[<class '__main__.A'>, <class '__main__.B'>, <class '__main__.E'>, <class '__main__.C'>, <class '__main__.F'>, <class '__main__.D'>, <class '__main__.G'>, <class 'object'>]

注意:可通过mro列表展示继承顺序。

重用父类方法的两种方式

一、方式一

继承重用父类方法方式一:指名道姓的使用

  • 与继承无关
  • 如果继承了多个父类,super是按照mro列表找,那么此时指名道姓地使用可以抛开mro列表的查找顺序,进行特殊调用
class A:
    def __init__(self,name,age):
        self.name = name
        self.age = age
        
class Person:
    school = 'oldboy'
    def __init__(self,name,age):
        self.name = name
        self.age = age
    def study(self):
        print('study....')

class Teacher(Person):
    def __init__(self,name,age,level):
        A.__init__(self,name,age)   #A作为类,对于init需传入三个参数
        self.level = level

class Student(Person):
    school = 'yyyy'
    def __init__(self,name,age,course):
        #如何重用父类的__init__方法
        Person.__init__(self,name,age)  #Person作为类,对于init需传入三个参数
        self.course = course
    def study(self):
        Person.study(self)
        print("%s学生在学习"%self.name)


stu1=Student('wed',19,"Python")
print(stu1.school)
stu1.study()

#yyyy
#study....
#wed学生在学习

二、方式二

继承重用父类方法方式一:通过super关键字(与继承有关)

class Person(object):
    school = 'oldboy'
    def __init__(self,name,age):
        self.name=name
        self.age=age
    def study(self):
        print('study....')

class Student(Person):
    school = 'yyyy'
    def __init__(self,name,age,course):
        #super() 会按照mro列表拿到父类对象
        #对象来调用绑定方法,不需要传递第一个参数(self)
        super().__init__(name,age)  #super()取出的是对象,所以第一个参数无需传参
        #经典类和新式类
        #经典类中必须这么写(py3中没有经典类),都用上面那种方式写
        # super(Student,self).__init__(name,age)
        self.course=course
    def study(self):
        # Person.study(self)
        super().study()
        # print("%s学生在学习"%self.name)


stu1=Student('wed',19,"Python")
stu1.study()

#study....

修改参数值的四种方式

#修改学生姓名
stu=Student('nick',18)

#方式一
print(stu.name)
stu.name='tank'
print(stu.name)

#方式二:
stu.chang_name('tank')
print(stu.name)

#方式三
Student.chang_name(stu,'王二蛋')
print(stu.name)

#方式四

#定义了一个函数
def change_name(obj,name):
    #修改obj对象的name属性
    print('原来的名字是%s' % obj.name)
    obj.name=name
    print('修改的名字是%s' % obj.name)

change_name(stu,'二丫')
print(stu.name)

super的使用

# super是按照mro列表找
class A:
    def f1(self):
        print('A.f1')
        
class B:
    def f1(self):
        print('B.f1')
    def f2(self):
        print('B.f2')
        super().f1()
        # return 'xxxxx'

class C(B,A):  
#mro列表按照这个顺序, 注意这个顺序, 这个顺序报错
# class C(A,B):
    def f1(self):
        print('C.f1')

#C实例化产生一个对象
c=C()
# print(c.f2())
print(C.mro())
c.f2()   #C中找不到,再去B中找,打印B.f2,继续执行A中的f1,打印A.f1

#B.f2
#A.f1

猜你喜欢

转载自www.cnblogs.com/fxyadela/p/11418640.html
今日推荐