Python面向对象之继承和多态用法分析


Posted in Python onJune 08, 2019

本文实例讲述了Python面向对象之继承和多态用法。分享给大家供大家参考,具体如下:

Python 类的继承和多态

Python 类的继承

在OOP(Object Oriented Programming)程序设计中,当我们定义一个class的时候,可以从某个现有的class 继承,新的class称为子类(Subclass),而被继承的class称为基类、父类或超类(Base class、Super class)。

我们先来定义一个class Person,表示人,定义属性变量 name 及 sex (姓名和性别);

定义一个方法print_title():当sex是male时,print man;当sex 是female时,print woman。参考如下代码:

class Person(object):
  def __init__(self,name,sex):
    self.name = name
    self.sex = sex
  def print_title(self):
    if self.sex == "male":
      print("man")
    elif self.sex == "female":
      print("woman")
class Child(Person):              # Child 继承 Person
  pass
May = Child("May","female")
Peter = Person("Peter","male")
print(May.name,May.sex,Peter.name,Peter.sex)  # 子类继承父类方法及属性
May.print_title()
Peter.print_title()

而我们编写 Child 类,完全可以继承 Person 类(Child 就是 Person);使用 class subclass_name(baseclass_name) 来表示继承;

继承有什么好处?最大的好处是子类获得了父类的全部属性及功能。如下 Child 类就可以直接使用父类的 print_title() 方法

实例化Child的时候,子类继承了父类的构造函数,就需要提供父类Person要求的两个属性变量 name 及 sex:

在继承关系中,如果一个实例的数据类型是某个子类,那它也可以被看做是父类(May 既是 Child 又是 Person)。但是,反过来就不行(Peter 仅是 Person,而不是Child)。

继承还可以一级一级地继承下来,就好比从爷爷到爸爸、再到儿子这样的关系。而任何类,最终都可以追溯到根类object,这些继承关系看上去就像一颗倒着的树。比如如下的继承树:

Python面向对象之继承和多态用法分析

isinstance()   及  issubclass()

Python 与其他语言不同点在于,当我们定义一个 class 的时候,我们实际上就定义了一种数据类型。我们定义的数据类型和Python自带的数据类型,比如str、list、dict没什么两样。

Python 有两个判断继承的函数:isinstance() 用于检查实例类型;issubclass() 用于检查类继承。参见下方示例:

class Person(object):
  pass
class Child(Person):         # Child 继承 Person
  pass
May = Child()
Peter = Person()
print(isinstance(May,Child))     # True
print(isinstance(May,Person))    # True
print(isinstance(Peter,Child))    # False
print(isinstance(Peter,Person))   # True
print(issubclass(Child,Person))   # True

Python 类的多态

在说明多态是什么之前,我们在 Child 类中重写 print_title() 方法:若为male,print boy;若为female,print girl

class Person(object):
  def __init__(self,name,sex):
    self.name = name
    self.sex = sex
  def print_title(self):
    if self.sex == "male":
      print("man")
    elif self.sex == "female":
      print("woman")
class Child(Person):        # Child 继承 Person
  def print_title(self):
    if self.sex == "male":
      print("boy")
    elif self.sex == "female":
      print("girl")
May = Child("May","female")
Peter = Person("Peter","male")
print(May.name,May.sex,Peter.name,Peter.sex)
May.print_title()
Peter.print_title()

当子类和父类都存在相同的 print_title()方法时,子类的 print_title() 覆盖了父类的 print_title(),在代码运行时,会调用子类的 print_title()

这样,我们就获得了继承的另一个好处:多态

多态的好处就是,当我们需要传入更多的子类,例如新增 Teenagers、Grownups 等时,我们只需要继承 Person 类型就可以了,而print_title()方法既可以直不重写(即使用Person的),也可以重写一个特有的。这就是多态的意思。调用方只管调用,不管细节,而当我们新增一种Person的子类时,只要确保新方法编写正确,而不用管原来的代码。这就是著名的“开闭”原则:

  • 对扩展开放(Open for extension):允许子类重写方法函数
  • 对修改封闭(Closed for modification):不重写,直接继承父类方法函数

子类重写构造函数

子类可以没有构造函数,表示同父类构造一致;子类也可重写构造函数;现在,我们需要在子类 Child 中新增两个属性变量:mother 和 father,我们可以构造如下(建议子类调用父类的构造方法,参见后续代码):

class Person(object):
  def __init__(self,name,sex):
  self.name = name
  self.sex = sex
class Child(Person):        # Child 继承 Person
  def __init__(self,name,sex,mother,father):
    self.name = name
    self.sex = sex
    self.mother = mother
    self.father = father
May = Child("May","female","April","June")
print(May.name,May.sex,May.mother,May.father)
Person

若父类构造函数包含很多属性,子类仅需新增1、2个,会有不少冗余的代码,这边,子类可对父类的构造方法进行调用,参考如下:

class Person(object):
  def __init__(self,name,sex):
    self.name = name
    self.sex = sex
class Child(Person):             # Child 继承 Person
  def __init__(self,name,sex,mother,father):
    Person.__init__(self,name,sex)    # 子类对父类的构造方法的调用
    self.mother = mother
    self.father = father
May = Child("May","female","April","June")
print(May.name,May.sex,May.mother,May.father)

多重继承

多重继承的概念应该比较好理解,比如现在需要新建一个类 baby 继承 Child , 可继承父类及父类上层类的属性及方法,优先使用层类近的方法,代码参考如下:

class Person(object):
  def __init__(self,name,sex):
    self.name = name
    self.sex = sex
  def print_title(self):
    if self.sex == "male":
      print("man")
    elif self.sex == "female":
      print("woman")
class Child(Person):
  pass
class Baby(Child):
  pass
May = Baby("May","female")    # 继承上上层父类的属性
print(May.name,May.sex)
May.print_title()         # 可使用上上层父类的方法
class Child(Person):
  def print_title(self):
    if self.sex == "male":
      print("boy")
    elif self.sex == "female":
      print("girl")
class Baby(Child):
  pass
May = Baby("May","female")
May.print_title()        # 优先使用上层类的方法

希望本文所述对大家Python程序设计有所帮助。

Python 相关文章推荐
Python编程中的反模式实例分析
Dec 08 Python
python目录与文件名操作例子
Aug 28 Python
Python使用回溯法子集树模板获取最长公共子序列(LCS)的方法
Sep 08 Python
利用scrapy将爬到的数据保存到mysql(防止重复)
Mar 31 Python
python 实现将字典dict、列表list中的中文正常显示方法
Jul 06 Python
详解如何管理多个Python版本和虚拟环境
May 10 Python
python实现字符串完美拆分split()的方法
Jul 16 Python
调用其他python脚本文件里面的类和方法过程解析
Nov 15 Python
3种适用于Python的疯狂秘密武器及原因解析
Apr 29 Python
MoviePy简介及Python视频剪辑自动化
Dec 18 Python
基于Python实现的购物商城管理系统
Apr 27 Python
Python使用protobuf序列化和反序列化的实现
May 19 Python
Python基本数据结构之字典类型dict用法分析
Jun 08 #Python
Python学习笔记基本数据结构之序列类型list tuple range用法分析
Jun 08 #Python
Python面向对象之类的封装操作示例
Jun 08 #Python
Python面向对象之类和实例用法分析
Jun 08 #Python
Python学习笔记之自定义函数用法详解
Jun 08 #Python
Python3基础教程之递归函数简单示例
Jun 07 #Python
Python正则表达式匹配和提取IP地址
Jun 06 #Python
You might like
php设计模式 DAO(数据访问对象模式)
2011/06/26 PHP
php中日期加减法运算实现代码
2011/12/08 PHP
php下载文件超时时间的设置方法
2016/10/06 PHP
Laravel学习基础之migrate的使用教程
2017/10/11 PHP
PHP SPL 被遗落的宝石【SPL应用浅析】
2018/04/20 PHP
PHP实现防止表单重复提交功能【基于token验证】
2018/05/24 PHP
tp5修改(实现即点即改)
2019/10/18 PHP
javascript radio 联动效果
2009/03/04 Javascript
微博@符号的用户名提示效果。(想@到谁?)
2010/11/05 Javascript
jQuery Tools tab(幻灯片)
2012/07/14 Javascript
js打开新窗口方法整理
2014/02/17 Javascript
js判断上传文件类型判断FileUpload文件类型代码
2014/05/20 Javascript
深入JavaScript高级程序设计之对象、数组(栈方法,队列方法,重排序方法,迭代方法)
2015/12/01 Javascript
如何使用PHP+jQuery+MySQL实现异步加载ECharts地图数据(附源码下载)
2016/02/23 Javascript
基于JS如何实现类似QQ好友头像hover时显示资料卡的效果(推荐)
2016/06/09 Javascript
基于javascript实现按圆形排列DIV元素(三)
2016/12/02 Javascript
JavaScript实现选中文字提示新浪微博分享效果
2017/06/15 Javascript
JS插件clipboard.js实现一键复制粘贴功能
2020/12/04 Javascript
如何解决React官方脚手架不支持Less的问题(小结)
2018/09/12 Javascript
pm2发布node配置文件ecosystem.json详解
2019/05/15 Javascript
浅谈webpack 四个核心概念之Entry
2019/06/12 Javascript
[47:55]Ti4第二日主赛事败者组 NaVi vs EG 1
2014/07/20 DOTA
[00:12]2018DOTA2亚洲邀请赛 sylar表现SOLO技艺
2018/04/06 DOTA
python中from module import * 的一个坑
2014/07/20 Python
python自动翻译实现方法
2016/05/28 Python
微信小程序python用户认证的实现
2019/07/29 Python
使用Pyhton集合set()实现成果查漏的例子
2019/11/24 Python
解决TensorFlow调用Keras库函数存在的问题
2020/07/06 Python
HTML5自定义属性的问题分析
2019/08/16 HTML / CSS
美国维生素、补充剂、保健食品购物网站:Vitacost
2016/08/05 全球购物
数字漫画:comiXology
2020/06/13 全球购物
珍惜资源保护环境的建议书
2014/05/14 职场文书
校园广播稿100字
2014/10/06 职场文书
房产公证书样本
2015/01/23 职场文书
团员个人年度总结
2015/02/26 职场文书
市语委办2016年第十九届“推普周”活动总结
2016/04/05 职场文书