写在之前
在昨天的文章(
零基础学习 Python 之继承(一)
)我们开始了类的学习,昨天讲的第一部分(概念 & 单继承),如果你错过了昨天的文章,建议你回头看一下再回来看这一篇,下面开始今天的内容。
调用被覆盖的方法
我们昨天说过,如果子类里有和父类同样名称的方法和属性,那么父类相应的部分不再被继承到子类。那么如果有这么一种情况,如果子类还想继续使用父类的该方法,那么该怎么办?我们可以对子类做如下修改,例子还是昨天的那个例子:
classBoy(Person):
def__init__(self,name):
Person.__init__(self,name)
self.real_name ='snow'
defget_name(self):
returnself.name
请仔细观察 Boy 的初始化方法,与昨天的例子有所不同,为了能继续在子类中使用父类的初始化方法,以类方法的方式调用 Person.__init__(self,name),此外在子类的初始化方法的参数中,要增加相应的参数 name。
接下来让我们实例化子类:
if__name__ =="__main__":
lee = Boy('rocky')
print(lee.real_name)
print(lee.get_name())
此刻的运行结果估计你也能猜出来:
snow
rocky
这样使父类中被覆盖的方法能再次在子类中使用。但是上述的方式有一个问题,那就是如果父类的名称因为某种玄学的方式被改变了,子类所对应的父类的类名也要改,如果你忘记了改,就会出现异常,程序少还可以,程序如果特别多的话,你可能会忘记一两个地方,然后就苦逼的 debug 了。
你想我们号称简洁优雅的 Python 怎么可能会容忍这么费事的东西存在呢,于是 Python 创了一个非常巧妙的方法 --super!
classBoy(Person):
def__init__(self,name):
#Person.__init__(self,name)
super(Boy,self).__init__(name)
self.real_name ='snow'
defget_name(self):
returnself.name
在上面的代码中我们只修改了一处,运行程序后显示的结果和以前一样,当然关于 super 还有一些别的用法,在这不做深究,感兴趣的可以自行 Google。
多重继承
昨天的文章中我们学了单继承,所谓单继承就是只从一个父类那继承,推展开来,多重继承就是继承可以来自多个父类,即一个子类的父类不止一个。请看下面的例子:
classPerson:
defhands(self):
print('two hands')
defhair(self,color):
print('The hair color is: ',color)
classBoy:
age =23
defname(self):
print('The boy name is rocky')
classChildren(Person,Boy):
pass
if__name__ =="__main__":
lee = Children()
lee.hands()
lee.hair('black')
lee.name()
print(lee.age)
在上面的程序中,前面有两个类分别是 Person 和 Boy,然后第三个类是 Children,它继承了前面的两个类,继承的方法和单继承差不多,也是在类名后面的括号里把要继承的两个类的类名写上。接着我实例化了类 Children,既然它继承了上面的两个类,那么上面两个父类的方法就可以拿来用。
运行一下程序,结果如下所示:
two hands
The hair color is:black
The boy nameisrocky
23
由上面的几个例子我们已经能很清楚的知道继承的特点,接下来我们还有必要了解一下多重继承的顺序问题。在这里有一个小问题:如果一个子类继承了两个父类,并且两个父类中都有相同的属性或者方法,那么实例化之后的子类所调用的该属性或方法是属于哪个父类的呢?下面就让我们来试一下:
classP1:
defname(self):
print('name is P1')
classP2:
defname(self):
print('name is P2')
defage(self):
print('P2 age is 23')
classQ1(P1,P2):
pass
classQ2(P1,P2):
defage(self):
print('Q2 age is 110')
classA(Q1,Q2):
pass
if__name__ =="__main__":
print(A.__mro__)
cla = A()
cla.age()
cla.name()
上述程序的运行结果如下:
(, , , , , )
Q2 age is110
name is P1
其中 print(A.__mro__) 可以打印出类的继承顺序。如果要执行 age() 方法,首先要在 Q1 类中查看有没有这种方法,如果没有,再看 Q2 类,如果还是没有的话再看 Q1 类所继承的 P1 类,找到后就执行该方法,同样 name() 也是按照这样的顺序,在 Q2 类中就找到了该方法。
上述的这种对继承属性和方法的搜索叫做「广度优先搜索」,至于为什么是这样,感兴趣的可以去 Google 一下。
写在之后
类的继承就到这讲完了,本来明天想写「多态」来着,但是突然想到类的「方法」忘记讲了,所以明天会更新类的方法的内容,敬请期待。
如果你觉得文章对你有帮助的话,欢迎点赞转发,谢谢了。
The end。
一起学习新知识
领取专属 10元无门槛券
私享最新 技术干货