设为首页 收藏本站
查看: 1313|回复: 0

[经验分享] Python_类的继承

[复制链接]

尚未签到

发表于 2018-8-8 07:33:45 | 显示全部楼层 |阅读模式
  1.类的继承关系和生活中父亲、儿子、孙子之间的关系一样,Python中若A类继承B类,则A类称之为子类,B类称之为父类(也称为基类)。
  2.类的继承方式分为:单继承、多继承两种;
  类的单继承是指,A类只继承一个父类B,如下图所示:
DSC0000.jpg

  类的多继承是指,A类可以继承多个父类,如下图所示:
DSC0001.jpg

  3.类继承的顺序
  如果子类继承一个或多个父类时,子类属性是任何调用的呢?见下图实例,我们定义的患者类继承了医院类和卫生局类,问题1.患者类和医院类中具有登记的方法(regpatien),此时子类调用该方法时是怎样调用的呢?问题2.子类中没有addr的属性,而两个父类中存在addr属性,此时子类在调用addr属性时能否正常调用?如果能正常调用,调用的又是哪个父类的addr属性?
  问题1.见下图:
DSC0002.jpg

  问题2.1.如果子类继承父类的顺序为先Hospital后Healthbureau,如下图所示:
DSC0003.jpg

  问题2.2.如果子类继承父类的顺序为先Healthbureau后Hospital,如下图所示:
DSC0004.jpg

  总结:1.子类继承父类时,在子类进行属性调用的顺序为:先查找自己的属性字典,若自己的属性字典中无该属性,则会依次按照继承父类的顺序来依次查找父类的属性字典;2.子类继承父类,当父类和子类均有相同的属性时,子类并不会影响父类的属性。总结起来就是:按继承的顺序来依次查询属性,一旦查到则停止;子类和父类的属性相互独立,互不影响;子类可以调用父类的属性,反之不行;
  该部分的代码块为:
  

class Hospital():  "医院类-->父类"
  addr = "医院地址为:无锡市解放路"
  depertment = ["超声科","放射科","内镜科"]
  def __init__(self,name,type,price):
  self.name = name
  self.type = type
  self.price = price
  def regpatien(self):
  print("--->>医院正在登记患者")
  

  
class Healthbureau():
  "卫生局类"
  addr = "卫生局类地址为:无锡市中心大夏"
  def __init__(self,heigh,size):
  self.heigh =heigh
  self.size =size
  


  
#>  
class Patient(Healthbureau,Hospital):   #多继承,先Healthbureau后Hospital
  "患者类"
  def __init__(self,patientname,age,sex):
  self.patientname = patientname
  self.age = age
  self.sex =sex
  def regpatien(self):
  print("--->>患者已经成功成功")
  def tohispital(self):
  print("%s去%s检查"%(self.patientname,Hospital.depertment[2]))
  

  
#子类实例化
  
patient1 = Patient("李明",24,"男")
  
#父类Hospital实例化
  
hospital = Hospital("无锡市人民医院","江苏省无锡市人民大道","三甲")
  
#子类实例调用regpatien方法
  
patient1.regpatien()
  
#父类Hospital调用regpatien方法
  
hospital.regpatien()
  
#子类实例调用addr方法
  
print(patient1.addr)
  

  深度解析类继承顺序
  如何解析多层继承关系?
  多层继承在python2和python3中解析的顺序不同,python2中是深度优先的原则,python3中是以广度优先的原则。继承顺序见下图:
DSC0005.jpg

DSC0006.jpg

  继承原理:python到底是如何实现继承顺序的呢?对于你定义的每一个类,python会计算出一个方法解析顺序(MRO)列表,这个MRO列表就是一个简单的所有基类的线性顺序列表。
  为了实现继承,python会在MRO列表上从左到右查找基类,直到找到第一个匹配这个属性的类为止。而这个MRO列表的构造是通过一个C3线性化算法来实现的。这个算法实际上就是合并所有父类的,MRO列表并遵循如下三条准则:
  ① 子类会由于父类被检查;
  ② 多个父类会根据他们在列表中的顺序被检查;
  ③ 如果对于下一个类存在两个合法的选择,应选择第一个父类;
  为此我们可以直接使用子类的mro或者mro方法来查询它自身的继承顺序,如下图所示:
DSC0007.jpg

  4.接口继承
  从上面例子中我们可以看出,类的继承有2种含义,一是:子类继承基类的方法,并作出自己的扩展或改变(基类代码的重用);二是:声明某个子类兼容于某基类,父类定义一个接口类,子类继承接口类,并且实现接口类中定义的方法。
  实践中,继承的第一种含义常常不建议使用,它是利小于弊,会出现代码的强耦合,不利于后面的维护和扩展;但接口的第二中含义十分重要,又称之为’接口继承’。
  接口继承实质上是:“要求做出一个抽象,这个抽象规定了一个兼容接口,使得外部调用者无需了解具体细节,可一视同仁的处理实现了特定接口的所有对象。”这种在程序设计上称之为归一化。
  例如:定义一个学校的基类,学校有不能的课程、学校有不同的活动,但是幼儿园的课程只是简单的字母识别、数数等,而大学的课程包含了微积分、专业课程等。如下图所示,通过接口的继承来实现上面的要求:
DSC0008.jpg

  如果Kindergarten类或College类中没有定义course或activity函数时,实例化直接报错,如下图所示:
DSC0009.jpg

  所以,接口继承就是在基类中定义子类要实现的方法名称(使用@abc.abstractclassmethod来装饰该函数,但它并未无实际功能),这样继承它的子类就必须要自定义这个函数功能,若子类没有该函数,则开始实例化就会报错。
  这样我们如果知道某些类要实现某些相同名称但功能不能的函数时,就可以先定义一个父类,再在父类中定义必须要实现的功能。这样子类在继承父类时,就可以避免忘记必须要实现的功能函数了,它是用来规范子类的方法。实际上基类不用进行实例化操作,因为它完全没有意义。
  该部分的代码块为:
  

import abc  
class School(metaclass=abc.ABCMeta):
  "学校的基类"
  @abc.abstractclassmethod
  def course(self):
  "学校开课的方法"
  pass
  @abc.abstractclassmethod
  def activity(self):
  "校园活动的方法"
  pass
  

  
class Kindergarten(School):
  "幼儿园的类"
  def __init__(self,name,addr,number):
  self.name =name
  self.addr =addr
  self.number =number
  def course(self):
  "课程函数"
  print("%s开设了字母、识数等课程"%self.name)
  def activity(self):
  "比赛活动"
  print("%s参加了儿童舞蹈比赛"%self.number)
  

  
class College(School):
  "幼儿园的类"
  def __init__(self, name, addr, number):
  self.name = name
  self.addr = addr
  self.number = number
  # def course(self):
  #     "课程函数"
  #     print("%s开设了微积分、高等数学等课程" % self.name)
  def activity(self):
  "比赛活动"
  print("%s参加了大学口语比赛"%self.name)
  def  volunta(self):
  "义务活动"
  print("这是志愿者活动")
  

  
kindergarten =Kindergarten("文澜幼儿园","杭州市拱墅区",300)
  
kindergarten.activity()
  

  
college =College("浙江大学","杭州市上城区",65300)
  
college.course()

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.iyunv.com/thread-548380-1-1.html 上篇帖子: Python编写地区选择-Dict 下篇帖子: Python与Excel不得不说的事
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表