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>
>>>