Python攻城师的成长————面向对象的三大特征(继承、多态)
学习目标:
- 了解继承与多态的概念,重点是要学会运用继承去处理问题
学习内容:
继承
在面对对象程序设计中,当我们定义一个class的时候,可以从某个现有的class继承,新的class称为子类,而被继承的class称为基类、父类或超类。
为了便于理解,我们可以举例子说明一下:
比如,我们已经编写了一个名为Animal的class,有一个run()方法可以直接打印:
class Animal(object):def run(self):print('Animal is running...')
现在我们有了Animal这个类,基于这个动物类,我们可以再分出一个Dog类和Cat类。现在我们也想让这两个类拥有run方法,这时为了方便就可以去"借用"Animal类里的run方法:
class Dog(Animal):passclass Cat(Animal):pass
现在按照继承定义的说法,对Dog来说,Animal就是它的父类,对于Animal来说,Dog就是它的子类。Cat和Dog类似。
继承有什么好处?最大的好处是子类获得了父类的全部功能。由于Animial实现了run()方法,因此,Dog和Cat作为它的子类,什么事也没干,就自动拥有了run()方法:
dog = Dog()
dog.run()cat = Cat()
cat.run()'''
运行结果如下:Animal is running...
Animal is running...
'''
继承的特点:
在调用父类的方法时,需要加上父类的类名前缀,且需要带上self参数变量。区别于在类中调用普通函数时并不需要带上self参数
Python总是首先查找对应类型的方法,如果它不能在派生类中找到对应的方法,它才开始到父类中逐个查找。(先在本类中查找调用的方法,找不到才去父类中找)。
继承中父类:用于被继承的类,称之为父类,也叫做基类,或者超类。子类:继承其他类的类,称之为子类,也叫做派生类。
实现代码复用,减少代码量;拥有父类的所有功能,只需要编写子类附加的功能即可。
继承还可以一级一级地继承下来,就好比从爷爷到爸爸、再到儿子这样的关系。而任何类,最终都可以追溯到根类object,这些继承关系看上去就像一颗倒着的树。比如如下的继承树:
┌───────────────┐│ object │└───────────────┘│┌────────────┴────────────┐│ │▼ ▼┌─────────────┐ ┌─────────────┐│ Animal │ │ Plant │└─────────────┘ └─────────────┘│ │┌─────┴──────┐ ┌─────┴──────┐│ │ │ │▼ ▼ ▼ ▼
┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐
│ Dog │ │ Cat │ │ Tree │ │ Flower │
└─────────┘ └─────────┘ └─────────┘ └─────────┘
这时候就可以提到继承里的一个特殊情况了,在python里可能有别与Java,在java里是不能直接继承多个父类的,而python是可以的只要在子类的小括号里用逗号隔开就行了。
多继承
Python2.2之前类是没有共同的祖先的,之后,引入object类,它是所有类的共同祖先类object。Python2中为了兼容,分为古典类(旧式类)和新式类。Python3中全部都是新式类。新式类都是继承自object的,新式类可以使用super。
语法结构
class ClassName(父类列表:A,B,C,...):类的代码体
多继承的产生也就是为了去可以免除一些方法的反复编写,只要从写好的地方继承过了就可以了。由此就会带来一些缺点:
当类很多,继承复杂的情况下,继承路径太多,很难说清什么样的继承路径。Python语法是允许多继承,但Python代码是解释执行,只有执行到的时候,才发现错误。团队协作开发,如果引入多继承,那代码很有可能不可控。不管编程语言是否支持多继承,都应当避免多继承。Python的面向对象,我们看到的太灵活了,太开放了,所以要团队守规矩。
- 多继承很好的模拟了世界,因为事物很少是单一继承,但是舍弃简单,必然引入复杂性,带来了冲突。
- 多继承的实现会导致代码设计的复杂度增加,所以有些高级编程语言舍弃了类的多继承:C++支持多继承;Java舍弃了多继承。
- 实现多继承的语言,要解决二义性,深度优先或者广度优先。
多态
子类可以从父类继承相同的属性或者方法,比如相同的函数名,在子类中可以有不同的实现,即子类可以有自己的特殊性,这就叫做多态。
多态的话按照我的理解就是一个物体的多种形态,比如可口可乐,在原先的基础上现在又有了樱桃味的,无糖等等。就是让原本功能比较简单的类,去在原基础上可以添加其他功能,官方点说就是增加它的灵活性。
为了更加生动的理解多态,再次利用上面的例子:
现在就可以对子类增加一些方法,比如Dog类:
class Dog(Animal):def run(self):print('Dog is running...')def eat(self):print('Eating meat...')
现在就可以看出,其实多态是基于继承来完成的。你看到了,无论是Dog还是Cat,它们run()的时候,显示的都是Animal is running…,符合逻辑的做法是分别显示Dog is running…和Cat is running…,因此,对Dog和Cat类改进如下:
class Dog(Animal):def run(self):print('Dog is running...')class Cat(Animal):def run(self):print('Cat is running...')'''
再次运行,结果如下:Dog is running...
Cat is running...
'''
当子类和父类都存在相同的run()方法时,我们说,子类的run()覆盖了父类的run(),在代码运行的时候,总是会调用子类的run()。这样,我们就可以说多态是基于继承来完成的
。
现在就可以总结出实现多态有两个前提:
- 继承:多态必须发生在父类与子类之间
- 重写:子类重写父类方法
这时候就会有小白会问了那学了多态有什么用?
怎么说呢其实以上代码实际貌似没啥用,为什么一定要去定义通过同一个函数名?我定义run1、run2不可以吗?代码量也一样啊!
其实真正体验出多态好处的代码一般是这样写的
class Animal():def run(self):print("I am an Animal")class Dog(Animal):def run(self):print("I am a dog")class Cat(Animal):def run(self):print("I am a cat")def func(obj):obj.run()if __name__ == "__main__":dog=Dog()cat=Cat()func(dog)func(cat)
仅仅需要一个函数,就可以把不同对象的run函数表现出来了。这就增加了程序的灵活性,以不变应万变,不管你类中的run()写得如何得天花乱坠,我都可以用一个统一的形式来调用。另外,它增加了程序的可扩展性,不管是我们或者调用者,如果想增加新的功能,都不需要修改原来的代码。
如,我想新增一个bird类,仅需增加以下代码,无需修改原来的。
class Bird(Animal):def run(self):print("I am a bird")
对于调用者,也仅需增加以下代码,无需修改原来的。
bird=Bird()
func(bird)
所以说多态有什么用?一是增加程序的灵活性,二是增加程序的可扩展性。
静态语言 vs 动态语言
对于静态语言(例如Java)来说,如果需要传入Animal类型,则传入的对象必须是Animal类型或者它的子类,否则,将无法调用run()方法。
对于Python这样的动态语言来说,则不一定需要传入Animal类型。我们只需要保证传入的对象有一个run()方法就可以了:
class Timer(object):def run(self):print('Start...')
这就是动态语言的“鸭子类型”,它并不要求严格的继承体系,一个对象只要“看起来像鸭子,走起路来像鸭子”,那它就可以被看做是鸭子。
Python的“file-like object“就是一种鸭子类型。对真正的文件对象,它有一个read()方法,返回其内容。但是,许多对象,只要有read()方法,都被视为“file-like object“。许多函数接收的参数就是“file-like object“,你不一定要传入真正的文件对象,完全可以传入任何实现了read()方法的对象。
学习时间:
- 周一至周五晚上 7 点—晚上9点
- 周六上午 9 点-上午 11 点
- 周日下午 3 点-下午 6 点
学习产出:
- 技术笔记 2 遍
- CSDN 技术博客 3 篇
Python攻城师的成长————面向对象的三大特征(继承、多态)相关推荐
- Python攻城师的成长————网络编程(socket套接字、通信循环、链接循环、黏包问题)
今日学习目标 学习什么是socket套接字,并依靠它去处理TCP协议等网络编程问题 文章目录 今日学习目标 学习内容 一. socket套接字 1.什么是socket 2.套接字发展史及分类 3.套接 ...
- Python攻城师的成长————模块突破(collections、time与datetime、random随机数模块)
今日学习目标: 学习并应用collections.time与datetime.random随机数模块知识 今日学习内容: collections模块 time与datetime模块 random随机数 ...
- Python攻城师的成长————ORM查询
今日学习目标 熟悉掌握ORM语法操作 文章目录 今日学习目标 学习内容 一.神奇的双下划线查询 二.orm创建外键关系 三.外键字段的增删改查 四.正反向的概念 五.ORM多表查询 正向查询 反向查询 ...
- Python攻城师的成长————MySQL数据库关键字
今日学习目标 熟悉关键字用法,掌握多表查询思路 文章目录 今日学习目标 学习内容 一.查询关键字 查询关键字之having过滤 查询关键字之distinct去重 查询关键字之order by排序 查询 ...
- Python攻城师的成长————css语法、伪元素选择器(部分)
今日学习目标 熟悉并掌握css中各种修改属性的方法. 文章目录 今日学习目标 学习内容 一.伪元素选择器 css操作文本内容 选择器优先级 二.css修改属性 css修改文字属性 css修改字体属性 ...
- Python攻城师的成长————Django框架(csrf相关装饰器、基于中间件思想编写项目、auth认证模块)
今日学习目标 逐步掌握csrf相关装饰器.基于中间件思想编写项目.auth认证模块知识点 文章目录 今日学习目标 学习内容 一. csrf相关装饰器 二.基于中间件思想编写项目 三.auth认证模块 ...
- 面向对象的三大特征继承,封装和多态性
目录 1.封装 2.继承 3.多态 面向对象的三大特征: 1.继承2.封装3.多态性 1.封装 把类中的属性私有化,模块化及信息隐蔽,也就是一个类把自己内部的实现细节进行隐蔽只暴露对外的接口,封装又分 ...
- Python攻城师————前端学习(jQuery框架、第三方框架bootstrap框架)
今日学习目标 继续学习jQuery框架剩余的内容. 文章目录 今日学习目标 学习内容 一.jQuery操作标签 class操作 样式操作 位置操作 文本值操作 属性操作 文档处理操作 二.jQuery ...
- Python攻城师————MySQL数据库(自增、外键、关键字)
今日学习目标 正式学习MySQL数据库语句. 文章目录 今日学习目标 学习内容 一.自增特性 二.约束条件之外键 外键的定义 外键约束创建 三.查询关键字 查询关键字之select与from 查询关键 ...
最新文章
- Android EditText+ListPopupWindow实现可编辑的下拉列表
- 哈希表(散列查找)(c/c++)
- MapReduce-流量统计求和-Reducer和JobMain代码编写
- STL 之count,count_if,max,max_element,min,min_element和random_shuffle
- python中时间处理去空格去冒号_Python实用日期时间处理方法汇总
- 10-7 3-2-(b)查询由生产厂商B生产的所有产品的型号(model) 和价格(price) (10 分)
- linux 信号没有被处理方法,[计算机]Linux 信号signal处理机制.doc
- 计算机科学分为几个部分,计算机由几部分组成各部分的功能是什么
- 微软发布Azure Storage不可变存储功能的正式版本
- maya python 开根号_maya python
- ionic路由(一)
- golang map合并_Golang之流式编程
- 方德系统装exe文件_国产x86处理器+中科方德定制Linux 完美运行exe
- 山东科技大学计算机基础知识,山东科技大学_计算机操作系统试题
- shell 脚本中常用的列表
- CRM 客户管理系统C#源码
- one algorithm a day keeps the doctor away -- BubbleSort
- SQL审核 | 如何利用 OpenAPI 实现自己的扫描任务
- Python实用案例
- java实现QQ微信扫码登录