13.11 继承
继承描述了基类的属性如何"遗传”给派生类。一个子类可以继承它的基类的任何属性,不管是数据属性还是方法。
>>> class P(object):
... "current is P"
... def __init__(self):
... print "Created an instance of ", self.__class__.__name__
...
>>> class C(P):
... "current is C"
... pass
...
>>> C()
Created an instance of C
<__main__.C object at 0x00F8B6F0>
>>> C.__doc__
'current is C'
>>>
C没有声明__init__()方法,然而类C的实例c被创建时,还是会有输出信息。原因在于C继承了P的__init__()。__bases__元组列出了其父类P。需要其注意的是文档字符串对类,函数/方法,还有模块来说是唯一的,所以特殊属性__doc__不会从基类中继承过来。
13.11.1 __bases__类属性
>>> class TheClass:
... pass
...
>>> TheClass.__bases__
()
>>> class TheClass2(object):
... pass
...
>>> TheClass2.__bases__
(<type 'object'>,)
>>>
__bases__类属性,对任何(子)类,它是一个包含其父类(parent)的集合的元组。我们明确指出“父类”是相对所有基类而言的。那些没有父类的类(经典类),他们的__bases__属性为空。
13.11.2 通过继承覆盖方法
>>> class P(object):
... def foo(self):
... print 'Hi, I am P-foo()'
...
>>> p = P()
>>> p.foo()
Hi, I am P-foo()
>>> class C(P):
... def foo(self):
... print 'Hi, I am C_foo()'
...
>>> c = C()
>>> c.foo()
Hi, I am C_foo()
>>> P.foo(c)
Hi, I am P-foo()
>>>
子类的方法如果有特定或不同的功能则可以覆盖基类的方法。(override)
一个更好的办法是使用super()内建方法:
>>> class P(object):
... def foo(self):
... print 'Hi, I am P-foo()'
...
>>> class C(P):
... def foo(self):
... super(C,self).foo()
... print 'Hi, I am C-foo()'
...
>>> C().foo()
Hi, I am P-foo()
Hi, I am C-foo()
>>>
super()内建方法不但能找到基类方法,而且还能为我们传进self。
如果你在子类中覆盖了__init__(),子类被实例化时,基类的__init__()就不会被自动调用。
>>> class P(object):
... def __init__(self):
... print 'current is P class~~~'
...
>>> class C(P):
... def __init__(self):
... super(C, self).__init__()
... print 'current is C class~~~'
...
>>> C()
current is P class~~~
current is C class~~~
<__main__.C object at 0x00F6E7F0>
>>>