Python类的继承和多态代码详解


Posted in Python onDecember 27, 2017

Python类的继承

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

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

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

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);使用classsubclass_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,printboy;若为female,printgirl

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的子类时,只要确保新方法编写正确,而不用管原来的代码。这就是著名的“开闭”原则:

对扩展开放(Openforextension):允许子类重写方法函数

对修改封闭(Closedformodification):不重写,直接继承父类方法函数

子类重写构造函数

子类可以没有构造函数,表示同父类构造一致;子类也可重写构造函数;现在,我们需要在子类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编码时应该注意的几个情况
Mar 04 Python
python动态监控日志内容的示例
Feb 16 Python
Django实现自定义404,500页面教程
Mar 26 Python
快速了解Python开发中的cookie及简单代码示例
Jan 17 Python
使用NumPy和pandas对CSV文件进行写操作的实例
Jun 14 Python
在Python运行时动态查看进程内部信息的方法
Feb 22 Python
简单了解python gevent 协程使用及作用
Jul 22 Python
Django REST Framework序列化外键获取外键的值方法
Jul 26 Python
python实发邮件实例详解
Nov 11 Python
Python列表倒序输出及其效率详解
Mar 04 Python
pytorch 限制GPU使用效率详解(计算效率)
Jun 27 Python
python UDF 实现对csv批量md5加密操作
Jan 01 Python
快速查询Python文档方法分享
Dec 27 #Python
Java及python正则表达式详解
Dec 27 #Python
python matplotlib画图实例代码分享
Dec 27 #Python
python爬虫使用cookie登录详解
Dec 27 #Python
Python爬虫番外篇之Cookie和Session详解
Dec 27 #Python
Python并发编程协程(Coroutine)之Gevent详解
Dec 27 #Python
利用 python 对目录下的文件进行过滤删除
Dec 27 #Python
You might like
一拳超人中怪人协会钦定! S级别最强四人!
2020/03/02 日漫
PHP连接SQLSERVER 注意事项(附dll文件下载)
2012/06/28 PHP
深入浅析PHP7.0新特征(五大新特征)
2015/10/29 PHP
php提高脚本性能的4个技巧
2020/08/18 PHP
PHP实现简易图形计算器
2020/08/28 PHP
网页里控制图片大小的相关代码
2006/06/25 Javascript
用js实现控件的隐藏及style.visibility的使用
2013/06/14 Javascript
JS、CSS加载中的小问题探讨
2013/11/26 Javascript
jQuery中$.get、$.post、$.getJSON和$.ajax的用法详解
2014/11/19 Javascript
jQuery Form 表单提交插件之formSerialize,fieldSerialize,fieldValue,resetForm,clearForm,clearFields的应用
2016/01/23 Javascript
浅析JavaScript中命名空间namespace模式
2016/06/22 Javascript
怎样判断jQuery当前元素是隐藏还是显示
2016/11/23 Javascript
详解vuejs之v-for列表渲染
2017/06/22 Javascript
详解vue中点击空白处隐藏div的实现(用指令实现)
2018/04/19 Javascript
VUE-Table上绑定Input通过render实现双向绑定数据的示例
2018/08/27 Javascript
如何写好一个vue组件,老夫的一年经验全在这了(推荐)
2019/05/18 Javascript
Layui Form 自定义验证的实例代码
2019/09/14 Javascript
微信小程序使用GoEasy实现websocket实时通讯
2020/05/19 Javascript
[44:58]2018DOTA2亚洲邀请赛 4.5 淘汰赛 LGD vs Liquid 第二场
2018/04/06 DOTA
[44:40]Spirit vs Navi Supermajor小组赛 A组败者组第一轮 BO3 第一场 6.2
2018/06/03 DOTA
python 输出一个两行字符的变量
2009/02/05 Python
Python中实现对Timestamp和Datetime及UTC时间之间的转换
2015/04/08 Python
Python实现好友全头像的拼接实例(推荐)
2017/06/24 Python
Pandas删除数据的几种情况(小结)
2019/06/21 Python
python自动化unittest yaml使用过程解析
2020/02/03 Python
Django 设置admin后台表和App(应用)为中文名的操作方法
2020/05/10 Python
解决pip install psycopg2出错问题
2020/07/09 Python
极度干燥澳大利亚官方网站:Superdry澳大利亚
2019/03/28 全球购物
妇产科护士自我鉴定
2013/10/15 职场文书
数控技术应届生求职信
2013/11/13 职场文书
大学生职业生涯规划书范文
2014/01/04 职场文书
企业优秀员工事迹材料
2014/05/28 职场文书
巴西世界杯32强口号
2014/06/05 职场文书
大学奖学金获奖感言
2014/08/15 职场文书
行政执法队伍作风整顿剖析材料
2014/10/11 职场文书
详解PHP服务器如何在有限的资源里最大提升并发能力
2021/05/25 PHP