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 相关文章推荐
Python3指定路径寻找符合匹配模式文件
May 22 Python
django接入新浪微博OAuth的方法
Jun 29 Python
python实现报表自动化详解
Nov 16 Python
SVM基本概念及Python实现代码
Dec 27 Python
python读取图片任意范围区域
Jan 23 Python
Python参数解析模块sys、getopt、argparse使用与对比分析
Apr 02 Python
使用Flask-Cache缓存实现给Flask提速的方法详解
Jun 11 Python
django多种支付、并发订单处理实例代码
Dec 13 Python
通过cmd进入python的步骤
Jun 16 Python
python 读取.nii格式图像实例
Jul 01 Python
numba提升python运行速度的实例方法
Jan 25 Python
利用Opencv实现图片的油画特效实例
Feb 28 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
第八节--访问方式
2006/11/16 PHP
php下获取Discuz论坛登录用户名、用户组、用户ID等信息的实现代码
2010/12/29 PHP
php5.3中连接sqlserver2000的两种方法(com与ODBC)
2012/12/29 PHP
谈谈JavaScript中的函数与闭包
2013/04/14 Javascript
JS、CSS加载中的小问题探讨
2013/11/26 Javascript
JavaScript及jquey实现多个数组的合并操作
2014/09/06 Javascript
删除Javascript Object中间的key
2014/11/18 Javascript
js实现有时间限制消失的图片方法
2015/02/27 Javascript
JavaScript模拟文件拖选框样式v1.0的实例
2017/08/04 Javascript
浅谈ajax请求不同页面的微信JSSDK问题
2018/02/26 Javascript
Vue与Node.js通过socket.io通信的示例代码
2018/07/25 Javascript
解决Vue.js由于延时显示了{{message}}引用界面的问题
2018/08/25 Javascript
JS调用安卓手机摄像头扫描二维码
2018/10/16 Javascript
vue的三种图片引入方式代码实例
2019/11/19 Javascript
vue 查看dist文件里的结构(多种方式)
2020/01/17 Javascript
[37:22]DOTA2上海特级锦标赛D组资格赛#2 Liquid VS VP第一局
2016/02/28 DOTA
python读写二进制文件的方法
2015/05/09 Python
浅谈使用Python变量时要避免的3个错误
2017/10/30 Python
python多线程使用方法实例详解
2019/12/30 Python
关于tensorflow的几种参数初始化方法小结
2020/01/04 Python
Python Django view 两种return的实现方式
2020/03/16 Python
Django serializer优化类视图的实现示例
2020/07/16 Python
基于Python实现体育彩票选号器功能代码实例
2020/09/16 Python
Pytho爬虫中Requests设置请求头Headers的方法
2020/09/22 Python
python和C++共享内存传输图像的示例
2020/10/27 Python
详解Python中如何将数据存储为json格式的文件
2020/11/18 Python
美国顶级奢侈茶:Mighty Leaf Tea(美泰茶)
2016/11/26 全球购物
德国排名第一的主题公园门票网站:Attraction Tickets Direct
2019/09/09 全球购物
美国最大的户外装备和服装购物网站:Backcountry
2019/10/15 全球购物
加拿大探亲邀请信
2014/01/28 职场文书
学生自我评价范文
2014/02/02 职场文书
信息管理与信息系统专业求职信
2014/06/21 职场文书
中学教师暑期培训方案
2014/08/27 职场文书
开会迟到检讨书范文
2015/05/06 职场文书
2015高中教师个人工作总结
2015/07/21 职场文书
vue引入Excel表格插件的方法
2021/04/28 Vue.js