热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

【python小课堂专栏】python小课堂22面向对象(四)

python小课堂22–面向对象(四)前言本节介绍面向对象的“继承”特性,这将是面向对象篇最后的基础部分,随后我会画出一个思维导图来总结下这一个月以来面向对象设计到的知识点。面向对

python小课堂22 – 面向对象(四)

前言

本节介绍面向对象的“继承”特性,这将是面向对象篇最后的基础部分,随后我会画出一个思维导图来总结下这一个月以来面向对象设计到的知识点。

面向对象的三大特征分别为:封装、继承、多态。 封装实际上就是上次讲的私有化,但是封装是一种思想,它所涉及的东西非常广,后续在慢慢补充,忘记的可以看下上次的总结。python小课堂21 – 面向对象(三)

而多态打算作为后续的进阶知识点来介绍。所以基础部分到继承就会将面向对象作为一个完结。废话不多说了,进入正题吧。

继承

何谓继承?在现实世界,比如爸爸到了一定年龄终归要留下一笔财富,而此时的财富一般就由儿子来继承。这样一来原来属于爸爸的钱,儿子在继承这笔财富之后,便有了使用权。所以这里儿子是子类,爸爸是父类

而映射到计算机中也是一个道理,可以想象之前的python面向对象的章节中,我一直以女朋友作为例子来进行讲解,这里女朋友再往上抽象一层得到的是什么呢?女朋友可以归为人类这一范畴。所以我们可以说女朋友继承了人的基本特性,人都有名字,性别,年龄的属性,来看下女朋友的类是如何继承人的类去实现的:

父类(人类):

class Human(object):
"""人的初始化方法,传入名称和年龄"""
def __init__(self, name, age):
self.name = name
self.age = age
def say(self):
print(f'人的名字:{self.name}')
print(f'人的年龄:{self.age}')
def eat(self):
print('This \'s Human eat method!')

可以看到,上面的代码中将女票的姓名与年龄提到了人的初始化方法中,再来看下女票类的代码:

from toobject.python22 import Human
class GirlFriend(Human):
# 交过的女朋友个数
total_nums = 0
# 初始化构造方法
def __init__(self, name, age, weight):
self.weight = weight
# 行为,说出自己的特征
def eat(self):
print('Here \'s girlFriend eat method')
girlFriend = GirlFriend('女儿国公主', 18, 90)
girlFriend.say()

可以看到GirlFriend(Human):通过这样的形式来实现所谓的继承,调用时,我们可以直接调用父类的say()方法,来看下能否直接调用。
《【python小课堂专栏】python小课堂22 - 面向对象(四)》

报错了,可以看到英文大致意思是说女朋友这个类并没有name的属性!为什么呢?可以思考下,我们通过子类直接调用父类的方法,然后报错信息出现在了父类的代码上。

实际上因为我们在调用女朋友类的时候,没有将name、age属性向父类进行传递,所以在父类中的name、age属性是空的,所以会在打印时发生报错!

继承调用父类

原因既然知道了,那么一切都好说了,我们现在只需要在女朋友初始方法中调用人的初始方法,并将name、age参数传递到后面,即可实现调用父类的say()方法,来看下代码:

from toobject.python22 import Human
class GirlFriend(Human):
# 交过的女朋友个数
total_nums = 0
# 初始化构造方法
def __init__(self, name, age, weight):
Human.__init__(self, name, age)
self.weight = weight
# 行为,说出自己的特征
def eat(self):
print('Here \'s girlFriend eat method')
girlFriend = GirlFriend('女儿国公主', 18, 90)
girlFriend.say()
print(girlFriend.age)
print(girlFriend.name)

《【python小课堂专栏】python小课堂22 - 面向对象(四)》

通过Human.__init__(self, name, age)将外面的参数传入到父类中,成功调用了父类的方法以及属性,也就是人中的姓名和年龄,以及说话的方法。

继承中的super关键词

上面的写法大家可以想一想有没有什么问题呢?虽然确实可以通过用父类的类名来直接调用__init__方法进行初始化,而这种特性在之前的面向对象小课堂中也讲过,直接用类.方法是python这门语言的一种特性!忘记的话可以回顾:python小课堂19 – 面向对象篇(二)

假设后续我们要修改女朋友所继承的父类,不让她继承人类了,原本女儿国国王就是妖怪的化身!所以让她继承妖怪类好了…~那么此时我们就需要改两个地方了,如下图:

《【python小课堂专栏】python小课堂22 - 面向对象(四)》

要知道一点,写程序其实有一个本质,就是如果有改动的地方,尽量让自己写出的代码在原有的基础上进行最少的修改!这点也就是设计模式常说的开闭原则(听不懂的话忽略即可,有好奇心的宝宝可以去查查看咯…)

所以为了遵循以上的原则,我们将原有程序进行改装,就要用到标题4所说的super关键字了!super:超级的意思,因为有些语言中父类也叫超类,所以估计才会用super来作为调用父类的关键词吧,个人猜测…接下来看下如何进行调用呢?

from toobject.python22 import Human
from toobject.python22 import Human
class GirlFriend(Human):
# 交过的女朋友个数
total_nums = 0
# 初始化构造方法
def __init__(self, name, age, weight):
super(GirlFriend, self).__init__(name, age)
self.weight = weight
# 行为,说出自己的特征
def eat(self):
print('Here \'s girlFriend eat method')
girlFriend = GirlFriend('女儿国公主', 18, 90)
girlFriend.say()
print(girlFriend.age)
print(girlFriend.name)

《【python小课堂专栏】python小课堂22 - 面向对象(四)》

通过 super(GirlFriend, self).__init__(name, age)的调用方式,将子类以及self传入到super里,在调用父类的构造方法将参数传入即可!

仔细思考下,这样一来,我们如果改变了继承类,将女朋友的父类改为妖怪…那么只需要在class声明的小括号后修改就能达到目的了,同时实现了代码的最小改动!

继承中的重写

心细的同学在上面的子父类中发现了一个相同点,没错,就是它们都共同有一个名为eat()的方法函数。如果我此时用实例对象去调用eat(),你们猜会打印输出什么?

from toobject.python22 import Human
class GirlFriend(Human):
# 交过的女朋友个数
total_nums = 0
# 初始化构造方法
def __init__(self, name, age, weight):
super(GirlFriend, self).__init__(name, age)
self.weight = weight
# 吃
def eat(self):
print('Here \'s girlFriend eat method')
girlFriend = GirlFriend('女儿国公主', 18, 90)
girlFriend.eat()

《【python小课堂专栏】python小课堂22 - 面向对象(四)》

输出了子类eat()方法中的调用,说明了子类把父类的eat()覆盖掉了,说专业点就是传说中的重写! 那么问题来了,为什么会有重写呢?重写的好处是什么呢?

必然是扩展性与复用性!大家可以想想,女朋友继承了人类的特征,会吃!所以到具体类中,让“吃”具体化,女票有着一套自己吃东西的体系!

若既想保留人类的吃方法,又要凸显女朋友吃法的个性,那该如何是好呢?这点就利用了super关键字去解决了…!

from toobject.python22 import Human
class GirlFriend(Human):
# 交过的女朋友个数
total_nums = 0
# 初始化构造方法
def __init__(self, name, age, weight):
super(GirlFriend, self).__init__(name, age)
self.weight = weight
# 吃
def eat(self):
super(GirlFriend,self).eat()
print('Here \'s girlFriend eat method')
girlFriend = GirlFriend('女儿国公主', 18, 90)
girlFriend.eat()

《【python小课堂专栏】python小课堂22 - 面向对象(四)》

可以看到都输出了…

总结

总结一下,python的继承跟别的语言不太一样,比如Java类的继承,只能单继承,而Python不一样,Python自身可以多继承,也就是继承多个类,这点放到后面讲,因为是进阶的知识点。

到这里,我就将面向对象所有的基础点讲完了…来用思维导图做个总结吧!基础归基础,后续还有面向对象的进阶部分,敬请期待…思维导图如下:

《【python小课堂专栏】python小课堂22 - 面向对象(四)》

至此完!

有想交流沟通python相关知识的同学,欢迎关注公号:
《【python小课堂专栏】python小课堂22 - 面向对象(四)》


推荐阅读
  • golang常用库:配置文件解析库/管理工具viper使用
    golang常用库:配置文件解析库管理工具-viper使用-一、viper简介viper配置管理解析库,是由大神SteveFrancia开发,他在google领导着golang的 ... [详细]
  • 本文详细介绍了Java中org.neo4j.helpers.collection.Iterators.single()方法的功能、使用场景及代码示例,帮助开发者更好地理解和应用该方法。 ... [详细]
  • 本文详细介绍如何使用Python进行配置文件的读写操作,涵盖常见的配置文件格式(如INI、JSON、TOML和YAML),并提供具体的代码示例。 ... [详细]
  • Java 中的 BigDecimal pow()方法,示例 ... [详细]
  • 1:有如下一段程序:packagea.b.c;publicclassTest{privatestaticinti0;publicintgetNext(){return ... [详细]
  • 本文详细探讨了Java中的24种设计模式及其应用,并介绍了七大面向对象设计原则。通过创建型、结构型和行为型模式的分类,帮助开发者更好地理解和应用这些模式,提升代码质量和可维护性。 ... [详细]
  • 本文介绍了Java并发库中的阻塞队列(BlockingQueue)及其典型应用场景。通过具体实例,展示了如何利用LinkedBlockingQueue实现线程间高效、安全的数据传递,并结合线程池和原子类优化性能。 ... [详细]
  • 1.如何在运行状态查看源代码?查看函数的源代码,我们通常会使用IDE来完成。比如在PyCharm中,你可以Ctrl+鼠标点击进入函数的源代码。那如果没有IDE呢?当我们想使用一个函 ... [详细]
  • 本文详细介绍了Java中org.eclipse.ui.forms.widgets.ExpandableComposite类的addExpansionListener()方法,并提供了多个实际代码示例,帮助开发者更好地理解和使用该方法。这些示例来源于多个知名开源项目,具有很高的参考价值。 ... [详细]
  • 本文详细介绍了Akka中的BackoffSupervisor机制,探讨其在处理持久化失败和Actor重启时的应用。通过具体示例,展示了如何配置和使用BackoffSupervisor以实现更细粒度的异常处理。 ... [详细]
  • 本文将介绍如何编写一些有趣的VBScript脚本,这些脚本可以在朋友之间进行无害的恶作剧。通过简单的代码示例,帮助您了解VBScript的基本语法和功能。 ... [详细]
  • Explore a common issue encountered when implementing an OAuth 1.0a API, specifically the inability to encode null objects and how to resolve it. ... [详细]
  • 本文将介绍如何使用 Go 语言编写和运行一个简单的“Hello, World!”程序。内容涵盖开发环境配置、代码结构解析及执行步骤。 ... [详细]
  • 深入解析Spring Cloud Ribbon负载均衡机制
    本文详细介绍了Spring Cloud中的Ribbon组件如何实现服务调用的负载均衡。通过分析其工作原理、源码结构及配置方式,帮助读者理解Ribbon在分布式系统中的重要作用。 ... [详细]
  • 本文深入探讨了 Java 中的 Serializable 接口,解释了其实现机制、用途及注意事项,帮助开发者更好地理解和使用序列化功能。 ... [详细]
author-avatar
mobiledu2502871343
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有