面向对象三大特性之一:继承

1、继承的简单语法

继承指的是类与类之间的关系,继承的功能之一就是用来解决代码重用问题

继承是一种创建新类的方式,在python中,新建的类可以继承一个或多个父类,父类又可以成为基类或超类,新建的类称为派生类或子类

class People:
    pass


class Male(People):
    pass


print(Male.__bases__)

# (<class '__main__.People'>,)

__base__只查看从左到右继承的第一个子类,__bases__则是查看所有继承的父类,python支持多继承,用逗号分隔开多个继承的类

2、属性查找

2.1 派生

通过继承的方式创建一个新的类,会继承父类的所有属性,查找属性先从实例中找,然后去类中找,然后去父类中找。
子类也可以添加自己新的属性,或者在子类中重新定义父类中的属性,在调用时以子类为准,这就是派生

2.2 继承的查找原理

为了实现继承,python会在MRO列表上从左到右开始查找,直到找到第一个匹配这个属性的类为止。

class People:
    pass


class Male(People):
    pass


print(Male.mro())

[<class '__main__.Male'>, <class '__main__.People'>, <class 'object'>]

Python中子类可以同时继承多个父类,如果继承了多个父类,那么属性的查找方式有两种,分别是:深度优先和广度优先
python3里统一都是新式类,按照广度优先的方式查找

2.2.1新式类和经典类

python2中才分经典类和新式类,没有继承object类的类以及该类的子类都是经典类,反之为新式类,python3中默认继承object类,都是新式类。

class People:
    pass

print(People.__bases__)
(<class 'object'>,)

2.2.2 广度优先

最后再找最高层类

class A:
    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')


f1 = F()
print(F.mro())
# [<class '__main__.F'>, <class '__main__.D'>,
# <class '__main__.B'>, <class '__main__.E'>,
# <class '__main__.C'>, <class '__main__.A'>,
# <class 'object'>]
class A:
    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 H(A):
    pass


class D(B):
    def test(self):
        print('from D')


class E(C):
    def test(self):
        print('from E')


class F(D):
    def test(self):
        print('from F')


class G(E):
    pass


class I(F, H, G):
    pass
print(I.mro())


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

3、子类调用父类的方法

在子类派生出的新方法中,往往需要重用父类的方法
有两种方式:
1、父类名.函数名(参数),不依赖继承,就是普通的父类函数调用。

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

    def run(self):
        pass


class Student(People):
    def __init__(self, name, age, sex, grade):
    #     self.name = name
    #     self.age = age
    #     self.sex = sex
        People.__init__(self, name, age, sex)  # 父类名+函数名
        self.grade = grade

    def learn(self):
        pass


s1 = Student('xiaohong', 18, 'male', '3')

print(s1.grade)

2、super()方法

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

    def run(self):
        pass


class Student(People):
    def __init__(self, name, age, sex, grade):
    #     self.name = name
    #     self.age = age
    #     self.sex = sex
    #     People.__init__(self, name, age, sex)  # 父类名+函数名
        super().__init__(name, age, sex)   # 没有self参数
        self.grade = grade

    def learn(self):
        pass


s1 = Student('xiaohong', 18, 'male', '3')

print(s1.grade)

super是依赖继承的,即使没有继承关系,也会按照mro顺序表查找:

class A:
    def test(self):
        super().f1()


class B:
    def f1(self):
        print('from B')


class C(A,B):
    pass


c = C()
c.test()
print(C.mro())

结果
from B
[<class '__main__.C'>, <class '__main__.A'>, <class '__main__.B'>, <class 'object'>]

4、组合重用

组合指的是,在一个类中以另外一个类的对象作为数据属性,称为类的组合。
组合就是在对象中添加一个数据属性,指向另外一个类的对象。
意思就是把另外一个类的对象当作一项属性添加到属性中。
继承是一种’是’的关系,老师和学生是人,组合是一种“有”的关系,老师有课程,学生有老师。
当类之间有显著不同,并且较小的类是较大的类所需要的组件时,用组合比较好

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


class Teacher(People):
    def __init__(self, name, age, sex):
        People.__init__(self, name, age, sex)  # 继承重用


class Student(People):
    def __init__(self, name, age, sex):
        People.__init__(self, name, age, sex)


class Course:
    def __init__(self, name, price):
        self.name = name
        self.price = price


student = Student('小明', 18, 'male')
teacher = Teacher('老李', 36, 'male')

# 为学生增加课程
python = Course('python', '3000')

student.course = python  # 组合重用

print(student.course)
# <__main__.Course object at 0x000002A1F34C5160>

print(student.course.name)
# python

# 为老师增加学生
teacher.student = student
print(teacher.student)
# <__main__.Student object at 0x000001DC13CE50F0>
print(teacher.student.name)
# 小明
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值