前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >零基础学习 Python 之继承(二)

零基础学习 Python 之继承(二)

作者头像
编程文青李狗蛋
发布2019-11-07 15:39:05
2590
发布2019-11-07 15:39:05
举报
写在之前

在昨天的文章(零基础学习 Python 之继承(一))我们开始了类的学习,昨天讲的第一部分(概念 & 单继承),如果你错过了昨天的文章,建议你回头看一下再回来看这一篇,下面开始今天的内容。

调用被覆盖的方法

我们昨天说过,如果子类里有和父类同样名称的方法和属性,那么父类相应的部分不再被继承到子类。那么如果有这么一种情况,如果子类还想继续使用父类的该方法,那么该怎么办?我们可以对子类做如下修改,例子还是昨天的那个例子:

代码语言:javascript
复制
class Boy(Person):
   def __init__(self,name):
       Person.__init__(self,name)
       self.real_name = 'snow'

   def get_name(self):
       return self.name

请仔细观察 Boy 的初始化方法,与昨天的例子有所不同,为了能继续在子类中使用父类的初始化方法,以类方法的方式调用 Person.__init__(self,name),此外在子类的初始化方法的参数中,要增加相应的参数 name。

接下来让我们实例化子类:

代码语言:javascript
复制
if __name__ == "__main__":
   lee = Boy('rocky')
   print(lee.real_name)
   print(lee.get_name())

此刻的运行结果估计你也能猜出来:

代码语言:javascript
复制
snow
rocky

这样使父类中被覆盖的方法能再次在子类中使用。但是上述的方式有一个问题,那就是如果父类的名称因为某种玄学的方式被改变了,子类所对应的父类的类名也要改,如果你忘记了改,就会出现异常,程序少还可以,程序如果特别多的话,你可能会忘记一两个地方,然后就苦逼的 debug 了。

你想我们号称简洁优雅的 Python 怎么可能会容忍这么费事的东西存在呢,于是 Python 创了一个非常巧妙的方法 -- super

代码语言:javascript
复制
class Boy(Person):
   def __init__(self,name):
       #Person.__init__(self,name)
       super(Boy,self).__init__(name)
       self.real_name = 'snow'

   def get_name(self):
       return self.name

在上面的代码中我们只修改了一处,运行程序后显示的结果和以前一样,当然关于 super 还有一些别的用法,在这不做深究,感兴趣的可以自行 Google。

多重继承

昨天的文章中我们学了单继承,所谓单继承就是只从一个父类那继承,推展开来,多重继承就是继承可以来自多个父类,即一个子类的父类不止一个。请看下面的例子:

代码语言:javascript
复制
class Person:
    def hands(self):
        print('two hands')
    def hair(self,color):
        print('The hair color is: ',color)

class Boy:
    age = 23
    def name(self):
        print('The boy name is rocky')

class Children(Person,Boy):
    pass

if __name__ == "__main__":
    lee = Children()
    lee.hands()
    lee.hair('black')
    lee.name()
    print(lee.age)

在上面的程序中,前面有两个类分别是 Person 和 Boy,然后第三个类是 Children,它继承了前面的两个类,继承的方法和单继承差不多,也是在类名后面的括号里把要继承的两个类的类名写上。接着我实例化了类 Children,既然它继承了上面的两个类,那么上面两个父类的方法就可以拿来用。

运行一下程序,结果如下所示:

代码语言:javascript
复制
two hands
The hair color is: black
The boy name is rocky
23

由上面的几个例子我们已经能很清楚的知道继承的特点,接下来我们还有必要了解一下多重继承的顺序问题。在这里有一个小问题:如果一个子类继承了两个父类,并且两个父类中都有相同的属性或者方法,那么实例化之后的子类所调用的该属性或方法是属于哪个父类的呢?下面就让我们来试一下:

代码语言:javascript
复制
class P1:
    def name(self):
        print('name is P1')

class P2:
    def name(self):
        print('name is P2')
    def age(self):
        print('P2 age is 23')

class Q1(P1,P2):
    pass

class Q2(P1,P2):
    def age(self):
        print('Q2 age is 110')

class A(Q1,Q2):
    pass

if __name__ == "__main__":
    print(A.__mro__)
    cla = A()
    cla.age()
    cla.name()

上述程序的运行结果如下:

代码语言:javascript
复制
(<class '__main__.A'>, <class '__main__.Q1'>, <class '__main__.Q2'>, <class '__main__.P1'>, <class '__main__.P2'>, <class 'object'>)
Q2 age is 110
name is P1

其中 print(A.__mro__) 可以打印出类的继承顺序。如果要执行 age() 方法,首先要在 Q1 类中查看有没有这种方法,如果没有,再看 Q2 类,如果还是没有的话再看 Q1 类所继承的 P1 类,找到后就执行该方法,同样 name() 也是按照这样的顺序,在 Q2 类中就找到了该方法。

上述的这种对继承属性和方法的搜索叫做「广度优先搜索」,至于为什么是这样,感兴趣的可以去 Google 一下。

写在之后

类的继承就到这讲完了,本来明天想写「多态」来着,但是突然想到类的「方法」忘记讲了,所以明天会更新类的方法的内容,敬请期待。

如果你觉得文章对你有帮助的话,欢迎点赞转发,谢谢了。

The end。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2018-08-21,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Python空间 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档