在我们教程的前一章中,我们已经介绍了继承,或者更具体的“单一继承”。正如我们所见,在这种情况下,一个类从一个类继承。另一方面,多重继承是一种特性,其中一个类可以从多个父类继承属性和方法。批评者指出,在钻石问题等情况下,多重继承伴随着高度的复杂性和模糊性。我们将在本章后面解决这个问题。
多重继承是“危险的”或“坏的”的普遍偏见主要是由多继承机制实现不佳的编程语言,尤其是对它的不当使用所滋生的。Java 甚至不支持多重继承,而 C++ 支持它。Python 有一种复杂且设计良好的多重继承方法。
一个类定义,其中子类 SubClassName 从父类 BaseClass1、BaseClass2、BaseClass3 等继承,如下所示:
class SubclassName(BaseClass1, BaseClass2, BaseClass3, ...):
经过
很明显,所有超类 BaseClass1、BaseClass2、BaseClass3... 也可以从其他超类继承。我们得到的是一个继承树。
示例:日历时钟
我们想通过一个例子来介绍多重继承的原理。为此,我们将实现独立的类:“时钟”和“日历”类。在此之后,我们将介绍一个“CalendarClock”类,顾名思义,它是“Clock”和“Calendar”的组合。CalendarClock 继承自“Clock”和“Calendar”。
Clock 类模拟时钟的滴答声。此类的一个实例包含时间,该时间存储在属性 self.hours、self.minutes 和 self.seconds 中。原则上,我们可以__init__
像这样编写方法和 set 方法:
def __init__(self,hours=0,minutes=0, seconds=0):
self._hours = 小时
self.__minutes = 分钟
self.__seconds = 秒
def 设置(自我,小时,分钟,秒 = 0):
self._hours = 小时
self.__minutes = 分钟
self.__seconds = 秒
我们决定反对这个实现,因为我们在 set 方法中添加了额外的代码来检查时间数据的合理性。我们也从__init__
方法中调用 set 方法,因为我们想绕过冗余代码。完整的时钟类:
"""
类 Clock 用于模拟时钟。
"""
class Clock ( object ):
def __init__ ( self , hours , minutes , seconds ):
"""
参数小时、分钟和秒必须是
整数,并且必须满足以下等式:
0 <= h < 24
0 <= m < 60
0 <= s < 60
"""
self 。set_Clock (小时, 分钟,
self , hours , minutes , seconds ):
"""
参数 hours, minutes 和 seconds 必须是
整数并且必须满足以下等式:
0 <= h < 24
0 <= m < 60
0 <= s < 60
"" "
if type ( hours ) == int and 0 <= hours and hours < 24 :
self 。_hours = hours
else :
引发 TypeError (“小时必须是 0 到 23 之间的整数!” )
if type ( minutes ) == int and 0 <= minutes and minutes < 60 :
self . __minutes = minutes
else :
raise TypeError (“分钟必须是 0 到 59 之间的整数!” )
如果 type ( seconds ) == int and 0 <= seconds and seconds < 60 :
self 。__seconds = seconds
else :
raise TypeError ( "Seconds must be integers between 0 and 59!" )
def __str__ ( self ):
return " {0:02d} : {1:02d} : {2:02d} " 。format ( self . _hours ,
self . __minutes ,
self . __seconds )
def tick ( self ):
"""
这个方法让时钟“滴答”,这意味着
内部时间将提前一秒。
示例:
>>> x = 时钟(12,59,59)
>>> 打印(x)
12:59:59
>>> x.tick()
>>> 打印(x)
13:00:00
>>> x.tick()
>>> print(x)
13:00:01
"""
if self . __seconds == 59 :
self . __seconds = 0
if self . __minutes == 59 :
self .
_hours == 23 :
自我。_hours = 0
其他:
自我。_hours += 1
else :
self 。__ 分钟 += 1
其他:
自我。__seconds += 1
if __name__ == "__main__" :
x = Clock ( 23 , 59 , 59 )
打印( x )
x 。打勾()
打印( x )
y = str ( x )
打印(类型( y ))
输出:
23:59:59
00:00:00
<类'str'>
让我们通过输入浮点数和字符串作为输入来检查我们的异常处理。我们还检查,如果超出预期值的限制会发生什么:
x = 时钟( 7.7 , 45 , 17 )
输出:
-------------------------------------------------- -------------------------
TypeError Traceback (最近一次调用最后一次)
<ipython-input-2-f91279ca09c6> in <module>
---- > 1 x = Clock ( 7.7 , 45 , 17 )
<ipython-input-1-ffb3e30af1a8> in __init__ (self, hours, minutes, seconds)
14 """
15
---> 16 self . set_Clock ( hours , minutes ,秒)
17
18 def set_Clock ( self , hours , minutes , seconds ) :
<ipython-input-1-ffb3e30af1a8> in set_Clock (self, hours, minutes, seconds)
28 self 。_hours = hours
29 else :
---> 30 raise TypeError ( "Hours must be integers between 0 and 23!" )
31 if type ( minutes ) == int and 0 <=分钟和分钟< 60 :
32 self . __minutes = minutes
TypeError : 小时数必须是 0 到 23 之间的整数!
x = 时钟( 24 , 45 , 17 )
输出:
-------------------------------------------------- -------------------------
TypeError Traceback (最近一次调用最后一次)
<ipython-input-4-36d0f83822b6> in <module>
----