零基础学 Python——面向对象-继承

亲爱的亦菲彦祖们,大家好!在前一篇博客中,我们深入探讨了类与对象的基本概念和使用方法。今天,我们将继续这段奇妙的编程旅程,迈向面向对象编程(OOP)的下一站——继承。别担心,我们依然会用生动有趣的方式,帮助大家轻松掌握继承的奥秘。让我们一起开启这段充满乐趣的学习之旅吧!

一. 继承的概念

在现实生活中,继承通常指的是子女继承父辈的财产或特质。那么,在编程世界中,继承又是什么意思呢?

继承是面向对象编程(OOP)的一个核心概念,它允许我们创建一个类(子类)来继承另一个类(父类)的属性和方法。通过继承,子类不仅拥有父类的所有特性,还可以扩展或修改这些特性,以适应更具体的需求。

举个生动的例子

想象一下,你是一位烘焙大师(父类),拥有制作各种甜点的秘方和技巧。你的学徒(子类)不仅学习并掌握了你的所有烘焙技巧,还根据自己的创意开发出了独特的甜点。学徒通过继承,既保留了大师的精髓,又增添了自己的特色。

在编程中,继承的主要目的是代码的复用逻辑的扩展。通过继承,我们可以避免重复编写相同的代码,同时让代码结构更加清晰、层次分明。


二. 单继承

单继承是指一个子类只继承自一个父类。这是最基本、最常见的继承方式。

生活中的单继承

让我们用一个简单的故事来理解单继承的概念。

故事主线:一个煎饼果子大师傅,在煎饼果子界摸爬滚打多年,研发出了一套精湛的煎饼果子制作技术。师傅决定将这套技术传授给他唯一、最得意的徒弟——泽言。

分析:徒弟泽言是否需要继承师傅的所有技术?当然!通过继承,泽言不仅拥有了师傅的煎饼果子配方,还能在此基础上进行创新。

编程中的单继承

让我们将这个故事转化为代码示例。

# 父类:Master(大师傅)
class Master(object):
    def __init__(self):
        self.secret = '[古法煎饼果子配方]'

    def make_cake(self):
        print(f'运用{self.secret}制作煎饼果子')

# 子类:Prentice(徒弟泽言)
class Prentice(Master):
    pass

# 创建徒弟对象
wanzi = Prentice()
print(wanzi.secret)  # 输出:[古法煎饼果子配方]
wanzi.make_cake()    # 输出:运用[古法煎饼果子配方]制作煎饼果子

解释

  • Prentice类通过括号继承了Master类,这意味着Prentice自动拥有Master的所有属性和方法。
  • 创建Prentice的实例wanzi后,可以直接访问Master中的secret属性和make_cake方法。

三. 多继承

有时候,一个子类需要继承多个父类的特性,这就是多继承

多继承的生活比喻

故事推进:泽言不仅继承了师傅的煎饼果子技术,还在寻找更多学习资源时,发现了青灯教育的高级煎饼果子课程。于是,泽言决定同时继承师傅和青灯教育的两套技术。

分析:通过多继承,泽言不仅掌握了师傅的古法配方,还学会了青灯教育的创新配方,使他的煎饼果子更加独特。

编程中的多继承

让我们通过代码示例来理解多继承。

# 父类1:Master(大师傅)
class Master(object):
    def __init__(self):
        self.secret = '[古法煎饼果子配方]'

    def make_cake(self):
        print(f'运用{self.secret}制作煎饼果子')

# 父类2:School(青灯教育)
class School(object):
    def __init__(self):
        self.secret = '[青灯煎饼果子配方]'

    def make_cake(self):
        print(f'运用{self.secret}制作煎饼果子')

# 子类:Prentice(徒弟泽言),继承自Master和School
class Prentice(Master, School):
    pass

# 创建徒弟对象
wanzi = Prentice()
print(wanzi.secret)  # 输出:[古法煎饼果子配方]
wanzi.make_cake()    # 输出:运用[古法煎饼果子配方]制作煎饼果子

注意

  • 当一个类继承自多个父类时,如果父类中有同名的属性或方法,子类会优先继承第一个父类的同名属性或方法。这遵循方法解析顺序(MRO)
  • 在上面的例子中,Prentice继承自MasterSchool,因此Mastersecretmake_cake被优先继承。

四. 子类重写父类同名属性和方法

有时候,子类需要对父类的某些属性或方法进行修改或扩展,这就需要**重写(Override)**父类的同名属性和方法。

生活中的重写

故事:泽言掌握了师傅和青灯教育的技术后,经过多年的研究,开发出了一套全新的、独创的煎饼果子配方。

分析:为了体现独创性,泽言决定重写父类中的secret属性和make_cake方法,使其使用自己的配方和制作方法。

编程中的重写

通过代码示例,我们来看看如何在子类中重写父类的属性和方法。

# 父类1:Master(大师傅)
class Master(object):
    def __init__(self):
        self.secret = '[古法煎饼果子配方]'

    def make_cake(self):
        print(f'运用{self.secret}制作煎饼果子')

# 父类2:School(青灯教育)
class School(object):
    def __init__(self):
        self.secret = '[青灯煎饼果子配方]'

    def make_cake(self):
        print(f'运用{self.secret}制作煎饼果子')

# 子类:Prentice(徒弟泽言),继承自School和Master,并重写父类属性和方法
class Prentice(School, Master):
    def __init__(self):
        self.secret = '[独创煎饼果子技术]'

    def make_cake(self):
        print(f'运用{self.secret}制作煎饼果子')

# 创建徒弟对象
wanzi = Prentice()
print(wanzi.secret)  # 输出:[独创煎饼果子技术]
wanzi.make_cake()    # 输出:运用[独创煎饼果子技术]制作煎饼果子

解释

  • Prentice类中,我们重新定义了__init__方法,修改了secret属性的值。
  • 同时,我们重写了make_cake方法,使其使用新的secret配方。
  • 通过这种方式,Prentice类的对象不仅继承了父类的属性和方法,还具备了自己的独特特性。

五. 子类调用父类的同名属性和方法

在某些情况下,子类希望在重写父类方法的同时,仍然能够调用父类的原始方法。这时,我们需要显式地调用父类的方法

生活中的调用

故事:虽然泽言开发了自己的独创配方,但为了满足不同顾客的需求,他希望能够同时制作师傅和青灯教育的传统煎饼果子。

分析:泽言需要在自己的make_cake方法中,调用父类的make_cake方法,以制作不同风格的煎饼果子。

编程中的调用

通过代码示例,我们来看如何在子类中调用父类的同名属性和方法。

# 父类1:Master(大师傅)
class Master(object):
    def __init__(self):
        self.kongfu = '[古法煎饼果子配方]'

    def make_cake(self):
        print(f'运用{self.kongfu}制作煎饼果子')

# 父类2:School(青灯教育)
class School(object):
    def __init__(self):
        self.kongfu = '[青灯煎饼果子配方]'

    def make_cake(self):
        print(f'运用{self.kongfu}制作煎饼果子')

# 子类:Prentice(徒弟泽言),继承自School和Master,并重写父类属性和方法
class Prentice(School, Master):
    def __init__(self):
        self.kongfu = '[独创煎饼果子技术]'

    def make_cake(self):
        print(f'运用{self.kongfu}制作煎饼果子')

    # 子类调用父类的同名方法和属性
    def make_master_cake(self):
        Master.__init__(self)          # 调用Master的__init__
        Master.make_cake(self)        # 调用Master的make_cake方法

    def make_school_cake(self):
        School.__init__(self)          # 调用School的__init__
        School.make_cake(self)        # 调用School的make_cake方法

# 创建徒弟对象
daqiu = Prentice()
daqiu.make_cake()           # 输出:运用[独创煎饼果子技术]制作煎饼果子
daqiu.make_master_cake()    # 输出:运用[古法煎饼果子配方]制作煎饼果子
daqiu.make_school_cake()    # 输出:运用[青灯煎饼果子配方]制作煎饼果子

解释

  • make_master_cake方法通过Master.__init__(self)Master.make_cake(self)显式调用了Master类的构造方法和make_cake方法。
  • 类似地,make_school_cake方法调用了School类的相关方法。
  • 这种方式允许子类在重写方法的同时,仍然能够访问和利用父类的方法和属性。

六. 多层继承

多层继承是指一个子类继承自另一个子类,形成多层次的继承关系。

生活中的多层继承

故事:多年后,泽言成为了煎饼果子界的传奇人物。他希望将所有的煎饼果子技术传承给自己的徒弟,让他们继承他的全部知识和经验。

分析:通过多层继承,泽言的徒弟不仅继承了泽言的技术,还间接继承了师傅和青灯教育的技术,实现了技术的全面传承。

编程中的多层继承

让我们通过代码示例,了解多层继承的实现方式。

# 父类1:Master(大师傅)
class Master(object):
    def __init__(self):
        self.kongfu = '[古法煎饼果子配方]'

    def make_cake(self):
        print(f'运用{self.kongfu}制作煎饼果子')

# 父类2:School(青灯教育)
class School(object):
    def __init__(self):
        self.kongfu = '[青灯煎饼果子配方]'

    def make_cake(self):
        print(f'运用{self.kongfu}制作煎饼果子')

# 子类:Prentice(徒弟泽言),继承自School和Master,并重写父类属性和方法
class Prentice(School, Master):
    def __init__(self):
        self.kongfu = '[独创煎饼果子技术]'

    def make_cake(self):
        print(f'运用{self.kongfu}制作煎饼果子')

    # 子类调用父类的同名方法和属性
    def make_master_cake(self):
        Master.__init__(self)
        Master.make_cake(self)

    def make_school_cake(self):
        School.__init__(self)
        School.make_cake(self)

# 多层继承:类Tusun继承自Prentice
class Tusun(Prentice):
    pass

# 创建对象
zx = Tusun()
zx.make_cake()           # 输出:运用[独创煎饼果子技术]制作煎饼果子
zx.make_master_cake()    # 输出:运用[古法煎饼果子配方]制作煎饼果子
zx.make_school_cake()    # 输出:运用[青灯煎饼果子配方]制作煎饼果子

解释

  • Tusun类继承自Prentice,而Prentice又继承自SchoolMaster
  • 通过多层继承,Tusun不仅继承了Prentice的独创技术,还能调用父类MasterSchool的配方制作方法。
  • 这种层次分明的继承结构,使得代码更具组织性和可扩展性。

七. super()调用父类方法

在多重继承和多层继承中,直接调用父类的方法可能会导致代码冗余和复杂性。为了简化父类方法的调用,Python提供了**super()**函数。

为什么使用super()

  • 自动化super()根据**方法解析顺序(MRO)**自动找到下一个父类,无需手动指定。
  • 简洁性:减少代码重复,使代码更加简洁易读。
  • 维护性:如果类的继承关系发生变化,使用super()的代码无需修改,避免潜在的错误。

编程中的super()

让我们通过代码示例,了解如何使用super()来调用父类的方法。

# 父类1:Master(大师傅)
class Master(object):
    def __init__(self):
        self.kongfu = '[古法煎饼果子配方]'

    def make_cake(self):
        print(f'运用{self.kongfu}制作煎饼果子')

# 父类2:School(青灯教育)
class School(Master):
    def __init__(self):
        super().__init__()  # 使用super()调用父类的__init__
        self.kongfu = '[青灯煎饼果子配方]'

    def make_cake(self):
        super().make_cake()  # 调用父类的make_cake方法
        print(f'运用{self.kongfu}制作煎饼果子')

# 子类:Prentice(徒弟泽言),继承自School
class Prentice(School):
    def __init__(self):
        super().__init__()
        self.kongfu = '[独创煎饼果子技术]'

    def make_cake(self):
        super().make_cake()
        print(f'运用{self.kongfu}制作煎饼果子')

    # 子类调用父类的同名方法和属性
    def make_old_cake(self):
        super().make_cake()

# 创建对象
wanzi = Prentice()
wanzi.make_old_cake()

解释

  • SchoolPrentice类的__init__make_cake方法中,我们使用super()来调用父类的方法。
  • super()根据MRO自动找到下一个父类,确保调用的是正确的父类方法。
  • 通过这种方式,make_old_cake方法可以一次性调用所有父类的make_cake方法,实现多重继承中的功能整合。

运行结果

运用[古法煎饼果子配方]制作煎饼果子
运用[青灯煎饼果子配方]制作煎饼果子
运用[独创煎饼果子技术]制作煎饼果子
运用[古法煎饼果子配方]制作煎饼果子
运用[青灯煎饼果子配方]制作煎饼果子
运用[独创煎饼果子技术]制作煎饼果子

总结

在这一部分的学习中,我们深入探讨了继承这一面向对象编程的核心概念。通过生动的故事和实用的代码示例,我们了解了以下内容:

  • 继承的概念:子类可以继承父类的属性和方法,实现代码复用和功能扩展。
  • 单继承:一个子类继承自一个父类,简单直接。
  • 多继承:一个子类继承自多个父类,灵活但需注意方法解析顺序。
  • 子类重写:子类可以重写父类的同名属性和方法,赋予其独特的特性。
  • 调用父类的方法和属性:通过显式调用或使用super(),子类可以访问父类的资源。
  • 多层继承:继承链条中的多层次结构,使得类的关系更加复杂和强大。
  • super()的使用:简化父类方法的调用,提高代码的可维护性和简洁性。

掌握了继承的这些知识,亦菲彦祖们将在编程中更加游刃有余,能够设计出更加高效、灵活的程序结构。记住,继承不仅是代码复用的工具,更是实现软件模块化和扩展性的关键。

继续前行

在未来的学习中,我们将进一步探索多态抽象等高级面向对象编程概念,帮助大家构建更加复杂和强大的软件系统。保持学习的热情,多动手实践,相信你们一定能在编程的道路上越走越远!

祝学习愉快,编程顺利!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

杨胜增

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值