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实现115网盘自动下载的方法
Sep 30 Python
MySQL中表的复制以及大型数据表的备份教程
Nov 25 Python
python字符串的常用操作方法小结
May 21 Python
Python的Flask框架应用程序实现使用QQ账号登录的方法
Jun 07 Python
Python使用QQ邮箱发送Email的方法实例
Feb 09 Python
Python实现的微信公众号群发图片与文本消息功能实例详解
Jun 30 Python
python @property的用法及含义全面解析
Feb 01 Python
python绘制热力图heatmap
Mar 23 Python
python解析多层json操作示例
Dec 30 Python
keras获得某一层或者某层权重的输出实例
Jan 24 Python
Python连接mysql数据库及简单增删改查操作示例代码
Aug 03 Python
编译 pycaffe时报错:fatal error: numpy/arrayobject.h没有那个文件或目录
Nov 29 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
url decode problem 解决方法
2011/12/26 PHP
PHP 伪静态技术原理以及突破原理实现介绍
2013/07/12 PHP
PHP设置images目录不充许http访问的方法
2016/11/01 PHP
解决在Laravel 中处理OPTIONS请求的问题
2019/10/11 PHP
Laravel配合jwt使用的方法实例
2020/10/25 PHP
JavaScript 创建运动框架的实现代码
2013/05/08 Javascript
$.extend 的一个小问题
2015/06/18 Javascript
js纯数字逐一停止显示效果的实现代码
2016/03/16 Javascript
浅谈JavaScript 执行环境、作用域及垃圾回收
2016/05/31 Javascript
JS实现鼠标移上去显示图片或微信二维码
2016/12/14 Javascript
js模拟微博发布消息
2017/02/23 Javascript
Javascript ES6中数据类型Symbol的使用详解
2017/05/02 Javascript
微信小程序封装http访问网络库实例代码
2017/05/24 Javascript
ECMAscript 变量作用域总结概括
2017/08/18 Javascript
jQuery实现鼠标响应式淘宝动画效果示例
2018/02/13 jQuery
angular 实现的输入框数字千分位及保留几位小数点功能示例
2018/06/19 Javascript
Vue源码中要const _toStr = Object.prototype.toString的原因分析
2018/12/09 Javascript
babel7.x和webpack4.x配置vue项目的方法步骤
2019/05/12 Javascript
jquery.pager.js分页实现详解
2019/07/29 jQuery
Nuxt使用Vuex的方法示例
2019/09/06 Javascript
[01:29:31]VP VS VG Supermajor小组赛胜者组第二轮 BO3第一场 6.2
2018/06/03 DOTA
Python中tell()方法的使用详解
2015/05/24 Python
在DigitalOcean的服务器上部署flaskblog应用
2015/12/19 Python
python对DICOM图像的读取方法详解
2017/07/17 Python
python 读取txt中每行数据,并且保存到excel中的实例
2018/04/29 Python
python selenium自动上传有赞单号的操作方法
2018/07/05 Python
pygame游戏之旅 python和pygame安装教程
2018/11/20 Python
Python输出\u编码将其转换成中文的实例
2018/12/15 Python
python函数enumerate,operator和Counter使用技巧实例小结
2020/02/22 Python
pandas数据分组groupby()和统计函数agg()的使用
2021/03/04 Python
工地标语大全
2014/06/18 职场文书
北京颐和园导游词
2015/01/30 职场文书
人事主管岗位职责
2015/02/04 职场文书
会计工作态度自我评价
2015/03/06 职场文书
病房管理制度范本
2015/08/06 职场文书
国庆节到了,利用JS实现一个生成国庆风头像的小工具 详解实现过程
2021/10/05 Javascript