1. 程式人生 > >Python類的繼承和方法重寫總結

Python類的繼承和方法重寫總結

python 類繼承和重寫

Python類的繼承和方法重寫總結

我們都知道類可以繼承,通過繼承可以實現代碼的復用,使代碼看起來更加簡潔

比如:

Class B(A):
Pass

定義了一個名為B的類,它繼承於A,我們把B叫做A的子類,A叫做B的超類(父類)。

方法重寫

當子類定義了一個和超類相同名字的方法時,那麽子類的這個方法將覆蓋超類相同的方法(或稱為重寫)

先借用兩個例子:

>>> class Bird:
...     def __init__(self):
...         self.hungry = True
...     def eat(self):
...         if self.hungry:
...             print 'Aaaah...'
...             self.hungry = False
...         else:
...             print 'No,thanks!'
...
>>> b = Bird()
>>> dir(b)
>>> b.eat()
Aaaah...
>>> b.eat()
No,thanks!
>>>

這個類定義了鳥的基本功能:吃

再定義一個類,SongBirdBird的子類,SongBird會唱歌

>>> class SongBird(Bird):
...     def __init__(self):
...         self.sound = 'Squawk!'
...     def sing(self):
...         print self.sound
...
>>> sb = SongBird()
>>> sb.sing()
Squawk!
>>> sb.eat()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 5, in eat
AttributeError: SongBird instance has no attribute 'hungry'
>>>

SongBirdBird的一個子類,他繼承了超類的eat方法,但調用時卻報錯了,提示沒有hungry屬性,為什麽會這樣呢?

原因是SongBird的構造方法__init__()重寫了,新的構造方法裏沒有任何關於hungry屬性的代碼。為了達到預期的效果,SongBird的構造方法必須調用父類的構造方法來確保進行基本的初始化。有兩種方法能達到這個目的:調用超類的構造方法的未綁定版本,或者使用super函數。

調用超類的構造方法的未綁定版本

>>> class SongBird(Bird):
...     def __init__(self):
...         Bird.__init__(self)
...         self.sound = 'Squawk!'
...     def sing(self):
...         print self.sound
...

SongBird類只添加了一行代碼Bird.__init__(self)

看下執行結果

>>> sb = SongBird()
>>> sb.eat()
Aaaah...
>>>

在調用一個實例的方法時,該方法的self參數會被自動綁定到實例上(這稱為綁定方法),但如果直接調用類的方法(比如Bird.__init__),就沒有實例被綁定,這樣的方法稱為未綁定方法。

通過將當前的實例作為self參數提供給未綁定方法,SongBird類就能使用其超類構造方法的所有實現。

Super函數

Super函數只能在新式類使用。當前類和對象可以作為super函數的參數使用,調用函數返回的對象的任何方法都是調用超類的方法,而不是當前類的方法。

那麽就可以不用在SongBird的構造方法使用Bird,而直接使用super(SongBird,self)註意是逗號,不是.

除此之外,__init__方法能以一種普通的(綁定)方式被調用

>>> __metaclass__ = type
>>> class Bird:
...     def __init__(self):
...         self.hungry = True
...     def eat(self):
...         if self.hungry:
...             print 'Aaaah...'
...             self.hungry = False
...         else:
...             print 'No,thanks!'
...

>>> class SongBird(Bird):
...     def __init__(self):
...         super(SongBird,self).__init__()
...         self.sound = 'Squawk!'
...     def sing(self):
...         print self.sound
...
>>> sb = SongBird()
>>> sb.eat()
Aaaah...
>>> sb.eat()
No,thanks!


Python類的繼承和方法重寫總結