Python3继承和多态的理解 - vip共享吧
  • 网站首页
  • IT技术笔记
    • Java教程
    • MySql数据库
    • PHP开发
    • Python教程
    • JavaScript
    • SEO优化
    • 常用工具
  • 好资源福利
    • 会员账号共享
  • 网站模板源码
    • 小程序源码
    • 网站源码
  • 共享网络资源
  • 更多功能
    • 留言吐槽
    • 文章归档
    • 我的邻居
    • 史上今日
    • 视频解析
    • 高清壁纸
    • 公告动态
    • 广告合作
    • 关于我们


导航菜单
  • 网站首页
  • IT技术笔记
    • Java教程
    • MySql数据库
    • PHP开发
    • Python教程
    • JavaScript
    • SEO优化
    • 常用工具
  • 好资源福利
    • 会员账号共享
  • 网站模板源码
    • 小程序源码
    • 网站源码
  • 共享网络资源
  • 更多功能
    • 留言吐槽
    • 文章归档
    • 我的邻居
    • 史上今日
    • 视频解析
    • 高清壁纸
    • 公告动态
    • 广告合作
    • 关于我们
Python

Python3继承和多态的理解

2024/9/6 韩俊  Python教程 436 0

面向对象的三大特征(封装,继承和多态),我们通过前面两节学习了封装的各种知识,本节课我们来学习继承和多态。

继承

在面向对象程序设计中,当我们定义一个类的时候, 可以从某个现有的类继承,该类称为子类,而被继承的类称为基类,父类或超类, 我们只需要在定义类的括号内加入父类的类名称就实现了继承。

class Animal():
    pass

class Cat(Animal):   # 继承 Animal
    pass

class Bird(Animal):  # 继承 Animal
    pass

Python 语言的哲学是:一切皆对象。Python 给我们提供一个万物之源的类,该类类名叫 object,Python 想让我们写的任何类都要继承这个 object 类,在 Python 3 中继承和不继承 object 的类都是一样的,但在 Python 2 中,继承和不继承 object 的类,对有继承关系的类是有区别的,大家有兴趣可以参考 Python 2 教程部分。所以我们以后写类要养成一个好习惯,特别是想要写出 Python 2 和 Python 3 通用的代码,我们自己写的类都要继承 object 类,在此我们只需要在被继承的父类 Animal 中继承 object 类即可,因为继承关系是往下传递的。

class Animal(object):  # 一切皆对象
    pass

class Cat(Animal):     # 继承 Animal
    pass

class Bird(Animal):    # 继承 Animal
    pass

子类拥有父类所有的属性和方法,比如我们有一个 Animal 类,该类有一个变量 name 和一个函数 talk,我们另定义类 Cat 和类 Bird 来继承 Animal 类。

class Animal(object):
    name = "Animal"  # Animal 类的属性

    def talk(self):  # Animal 类的方法
        print("Animal talking")

class Cat(Animal):
    pass

class Bird(Animal):
    pass


onecat = Cat()
onebird = Bird()

print(onecat.name)
onecat.talk()

print(onebird.name)
onebird.talk()

当然我们也可以在父类的构造函数中定义变量,子类的对象如果想拥有该变量,子类必须把子类对象本身传给父类, 用来替代父类对象本身,我们可以通过调用父类的构造函数把子类对象传过去。

class Animal(object):
    def __init__(self):
        self.name = "Animal"  # self 具体是什么,一切由调用者决定

    def talk(self):  # Animal 类的方法
        print("Animal talking")

class Cat(Animal):
    def __init__(self):
        Animal.__init__(self)  # 把子类对象本身传给父类的构造函数

class Bird(Animal):
    def __init__(self):
        Animal.__init__(self)  # 把子类对象本身传给父类的构造函数


onecat = Cat()    # 调用 Cat 类的构造函数,在 Cat 类的构造函数中,调用了 Animal 类的构造函数(参数为 onecat 对象本身)
onebird = Bird()  # 调用 Bird 类的构造函数,在 Bird 类的构造函数中,调用了 Animal 类的构造函数(参数为 onebird 对象本身)

print(onecat.name)
onecat.talk()

print(onebird.name)
onebird.talk()

当然,我们只要能把子类的对象传给父类,并且在父类中给该对象定义属性,子类对象都会拥有该属性。注意:我们一般习惯于在子类的构造函数中调用父类的构造函数来初始化属性,在此我们只是举个例子让大家明白这个机制。

class Animal(object):
    def __init__(self):
        self.name = "Animal"   # self 具体是什么,一切由调用者决定

    def what(self):            # self 具体是什么,一切由调用者决定
        self.what = 250

class Cat(Animal):
    def __init__(self):
        Animal.what(self)      # 把子类对象本身传给父类的 what 函数

    def haha(self):
        Animal.__init__(self)  # 把子类对象本身传给父类的构造函数


onecat = Cat()     # 调用 Cat 类的构造函数,在 Cat 类的构造函数中,调用了 Animal 类的 what 函数(参数为 onecat 对象本身)

print(onecat.name)  # 错误
print(onecat.what)  # 正确

onecat.haha()
print(onecat.name)  # 正确

如果我们在子类中不写构造函数,Python 解释器会自动给我们添加上构造函数,子类构造函数里面的代码和我们上面子类中写的一样。

class Animal(object):
    def __init__(self):
        self.name = "Animal"

    def talk(self):
        print("Animal talking")


'''
1.Cat 类中没有构造函数,Python 解释器会自动给 Cat 类添加构造函数。
2.添加的内容为:
def __init__(self):
    Animal.__init__(self)
'''
class Cat(Animal):
    pass



'''
1.Bird 类中有构造函数,Python 解释器不会再创建构造函数。
2.我们在子类中的构造函数中,并没有把 self 传给父类,
所以,Bird 类的对象没法拥有父类构造函数中定义的属性 name
'''
class Bird(Animal):
    def __init__(self):
        pass

onecat = Cat()
onebird = Bird()

print(onecat.name)  # 正确
onecat.talk()

print(onebird.name)  # 错误
onebird.talk()

再有继承关系的类中,我们也可以在子类中加入新的属性和函数。

class Animal(object):
    def __init__(self):
        self.name = "Animal"

    def talk(self):
        print("Animal talking")

class Cat(Animal):
    def __init__(self):
    self.beard = "Cat beard"  # 猫有胡须

    def getbeard(self):
    return "This is" + self.beard

class Bird(Animal):
    def __init__(self):
        self.wing = "Bird wing"    # 鸟有翅膀

    def fly(self):
        print("I'm flying")

onecat = Cat()
onebird = Bird()

print(onecat.beard)
print(onecat.getbeard())
print(onebird.wing)
onebird.fly()

在有继承关系的类设计中,我们一般习惯于把子类对象这些共有的属性定义在父类中, 而这些属性的值我们通过子类的对象来赋予。我们可以在子类的构造函数通过调用父类的构造函数传过去,调用父类构造函数有两种方法 (可以通过调用 Animal.__init__ 函数或者 super(类名, 对象).__init__ 函数)。

class Animal(object):
    def __init__(self, name):
        self.name = name

    def talk(self):
        print(self.name + "is talking")

class Cat(Animal):
    def __init__(self, name, beard):
        Animal.__init__(self, name) # 调用父类 Animal 的构造函数
        self.beard = beard

    def getbeard(self):
        return self.beard

class Bird(Animal):
    def __init__(self, name, wing):
        super(Bird, self).__init__(name)  # 调用父类 Animal 的构造函数
        self.wing = wing    # 鸟有翅膀

    def fly(self):
        print("I'm flying")

onecat = Cat(u"加菲猫", "Cat beard")
onebird = Bird(u"愤怒的小鸟", "Bird wing")

print(onecat.name)
onecat.talk()

print(onebird.name)
onebird.talk()

我们在此再次复习一个概念:类中的所有成员函数都是属于类的,因为成员函数(不包含里面的变量)是代码, 这些代码存放在代码段中,所有对象共用这份代码,所以不存在属于某个对象的成员函数; 而成员变量有属于对象的(在函数内部定义),也有属于类的(在类内非函数内部定义)。

class Animal(object):
    name = "Animal"                   # 属于类的成员变量
    def __init__(self):               # 成员函数都是属于类的,构造函数也是成员函数
        self.nameex = "Animalex"      # 属于 self 对象的成员变量

    def talk(self):                   # 成员函数都是属于类的
        self.nameexex = "Animalexex"  # 属于 self 对象的成员变量
        print("Animal talking")

如果我们子类中的属于类的变量或函数和父类中的属于类的变量或函数重名,通过子类的对象访问该重名变量或重名函数都是子类的。

class Animal(object):
    name = "Animal"

    def talk(self):
        print("Animal talking")

class Bird(Animal):
    name = "Bird"

    def talk(self):
        print("Bird talking")

onebird = Bird()
print(onebird.name)  # Bird 类的 talk 成员函数
onebird.talk()       # Bird 类的 name 成员变量

但是如果是子类属于对象的变量和父类对象中的变量重名,则根据对象本身赋值顺序而定(这是理所当然的正常语法)。

class Animal(object):
    def __init__(self):
        self.name = "Animal"

class Bird(Animal):
    def __init__(self):
        Animal.__init__(self)  # 在父类中先给 onebird 对象的 name 赋值为 "Animal"
        self.name = "Bird"     # 然后改写 onebird 对象的 name 值为 "Bird"

onebird = Bird()
print(onebird.name)  # "Bird"

#---------我是分割线---------
class Animal(object):
    def __init__(self):
        self.name = "Animal"

class Bird(Animal):
    def __init__(self):
        self.name = "Bird"     # 先给 onebird 对象的 name 赋值为 "Bird"
        Animal.__init__(self)  # 然后在父类中改写 onebird 对象的 name 值为 "Animal"

onebird = Bird()
print(onebird.name)  # "Animal"

多态

当子类和父类存在同名的成员函数时,通过某个子类的对象调用该函数,总是会调用相应子类的函数,该行为称为多态。

class Animal(object):
    def talk(self):
        print("Animal talking")

class Cat(Animal):
    def talk(self):
        print("Cat talking")

class Bird(Animal):
    def talk(self):
        print("Bird talking")

def func(animal):
    animal.talk()

onecat = Cat()
onebird = Bird()

func(onecat)     # "Cat talking"
func(onebird)    # "Bird talking"

Python中的多态和其它静态语言(比如 c++,java等)中多态的实现方法是不一样的, c++ 中是通过基类的指针或引用来实现运行时多态。由于 Python 是动态语言,并不需要提前给一个变量定义好类型,在 Python 中其实我们就是直接通过子类的对象调用子类中重新定义的该函数而已(这是理所当然的正常语法)。

本节重要知识点

理解 Python 继承中相应的语法。

弄明白 Python 是动态语言,多态是必然的。

点赞:0 分享

上一篇
python中的“一切皆对象”如何理解
下一篇
Python3的构造函数和访问控制
作者头像 作者名称 作者性别
韩俊

热门推荐

1 《Python编程从入门到精通》由浅入深地讲解Python语言开发
2 python3类和对象的概念
3 Python3函数参数详解
4 Python3的set类型
5 python argparse用法总结
6 Python序列化和反序列化

评论列表

取消回复

    •  
      Login

      韩俊

      趁你现在还有时间,尽你自己最大的努力,努力做成你最想做的那件事,成为你最想成为的那种人,过着你最想过的那种生活。这个世界永远比你想的要更精彩,不要败给生活。

      退出登陆
      • 10076文章
      • 455评论
      • 80微语
  • 广告赞助

  • 二零二五年06月
    一二三四五六日
          1
    2345678
    9101112131415
    16171819202122
    23242526272829
    30      
  • 分类

    • 网站模板源码
    • IT技术笔记
    • 好资源分享
    • 共享网络资源
  • 最新文章

      • 幼儿端午祝福语简短句
        • 端午简短祝福语送家人
          • 端午文案祝福语简短励志
            • 经典的黄句子
              • 经典黄色搞笑句子
                • 迷雾通:免费使用的VPN软件
                  • 任推邦:打造你的赚钱新途径!
                    • 任推邦是正规平台吗?任推邦邀请码多少?
  • 热门文章

    • 酷狗音乐VIP账号 酷狗音乐会员账号共享2017.01.29更新
    • 芒果tv vip会员账号 芒果tv会员账号共享2017.01.29更新
    • 爱奇艺vip账号 爱奇艺/PPS会员账号共享2016.12.12更新
    • 优酷/土豆vip会员账号 优酷会员账号共享2017.01.29更新
    • 活动:免费获得爱奇艺VIP/PPS会员账号50天以上的使用权!
    • 酷我音乐VIP账号 酷我音乐会员账号共享2016.12.31更新
    • 暴风影音会员账号 暴风影音会员账号共享2016.12.31更新
    • m1905会员账号 m1905会员账号共享2016.10.21更新
  • 最新评论

    • https://www.vipshare8.com/content/templates/meta/Static/images/tx/10.jpg

      你丫的 文章写得太好了 支持下!![F3...

    • https://www.vipshare8.com/content/templates/meta/Static/images/avatar.jpg

      很棒!刚在某网站看到这个,很欣赏,可惜下...

    • https://www.vipshare8.com/content/templates/meta/Api/qqtx.php/?qq=3861064027

      呃呃呃 oooo

    • https://www.vipshare8.com/content/uploadfile/202103/thum-490d1614564497.png

      回复了111:根据激活的时间有一年的有效期!

    • https://www.vipshare8.com/content/templates/meta/Api/qqtx.php/?qq=792480561

      到2025就到期了吗?

    • https://www.vipshare8.com/content/uploadfile/202103/thum-490d1614564497.png

      [blockquote]打卡时间:16:...

    • https://www.vipshare8.com/content/templates/meta/Static/images/tx/7.jpg

      俊哥,想借用迅雷一用!但需要手机验证!看...

    • https://www.vipshare8.com/content/templates/meta/Api/qqtx.php/?qq=3293901900

      感谢大大的分享

    • https://www.vipshare8.com/content/uploadfile/202103/thum-490d1614564497.png

      回复了好奥v:如果没有解析成功,可以切换接口...

    • https://www.vipshare8.com/content/templates/meta/Api/qqtx.php/?qq=131241242441

      现在视频解析网站怎么用不了啦?

  • 网站统计 I 当前在线:487人

    • 本站管理:1位
    • 用户总数:591位
    • 置顶文章:2篇
    • 日志总数:10076篇
    • 微语总数:80条
    • 评论总数:455条
    • 标签总数:83条
    • 页面总数:8页
    • 分类总数:14个
    • 链接总数:16条
    • 运行天数:3699天
    • 最后更新:5月26日
    • 登录
    • 注册
    • 找回
    Copyright © 2025vip共享吧网站地图 网站备案豫ICP备19004194号-1

    免责声明:本站资源仅供用于学习和交流,本站部分素材内容来源于网络,如有侵权/投稿等,请及时联系站长.

    • 首页
    • 秒懂百科 秒懂百科
    • 搜索
    • 史上今日

    大家都在搜

    • 土豆vip账号
    • 飞卢小说vip账号共享
    • qq音乐会员共享
    • chatGPT
    • 网易云音乐会员
    • swoole
    • pptv
    • seo优化
    • 微信小程序源码
    • 乐视会员账号共享
    • 腾讯视频会员账号
    • Python
    • Java教程
    • 开发工具
    • 咪咕会员账号
    • javascript教程
    • 
    • 