面向對象中super的作用


什么是super?

  super() 函數是用於調用父類(超類)的一個方法。
  super 是用來解決多重繼承問題的,直接用類名調用父類方法在使用單繼承的時候沒問題,但是如果使用多繼承,會涉及到查找順序(MRO)、重復調用(鑽石繼承)等種種問題。
  MRO 就是類的方法解析順序表, 其實也就是繼承父類方法時的順序表。

語法

以下是 super() 方法的語法:

super(type[, object-or-type])

參數

  ·type -- 類。

  ·object-or-type -- 類,一般是 self

Python3.x 和 Python2.x 的一個區別是: Python 3 可以使用直接使用 super().xxx 代替 super(Class, self).xxx :
Python3.x 實例:

class A:
    pass
class B(A):
    def add(self, x):
        super().add(x)

Python2.x 實例:

class A(object):   # Python2.x 記得繼承 object
    pass
class B(A):
    def add(self, x):
        super(B, self).add(x)

具體應用示例:

舉個例子

class Foo:  
  def bar(self, message):  
    print(message)  
>>> Foo().bar("Hello, Python.")  
Hello, Python.

  當存在繼承關系的時候,有時候需要在子類中調用父類的方法,此時最簡單的方法是把對象調用轉換成類調用,需要注意的是這時self參數需要顯式傳遞,例如:

復制代碼
class FooParent:  
  def bar(self, message):  
    print(message)  
class FooChild(FooParent):  
  def bar(self, message):  
    FooParent.bar(self, message)  
>>> FooChild().bar("Hello, Python.")  
Hello, Python.
復制代碼

  這樣做有一些缺點,比如說如果修改了父類名稱,那么在子類中會涉及多處修改,另外,Python是允許多繼承的語言,如上所示的方法在多繼承時就需要重復寫多次,顯得累贅。為了解決這些問題,Python引入了super()機制,例子代碼如下:

復制代碼
class FooParent:  
  def bar(self, message):  
    print(message)  
class FooChild(FooParent):  
  def bar(self, message):  
    super(FooChild, self).bar(message)  
  
>>> FooChild().bar("Hello, Python.")  
Hello, Python
復制代碼

  表面上看 super(FooChild, self).bar(message)方法和FooParent.bar(self, message)方法的結果是一致的,實際上這兩種方法的內部處理機制大大不同,當涉及多繼承情況時,就會表現出明顯的差異來,直接給例子:
代碼一:

復制代碼
class A:  
  def __init__(self):  
    print("Enter A")  
    print("Leave A")  
class B(A):  
  def __init__(self):  
    print("Enter B")  
    A.__init__(self)  
    print("Leave B")  
class C(A):  
  def __init__(self):  
    print("Enter C")  
    A.__init__(self)  
    print("Leave C")  
class D(A):  
  def __init__(self):  
    print("Enter D")  
    A.__init__(self)  
    print("Leave D")  
class E(B, C, D):  
  def __init__(self):  
    print("Enter E")  
    B.__init__(self)  
    C.__init__(self)  
    D.__init__(self)  
    print("Leave E")  
E()
復制代碼

結果為:

Enter E
Enter B
Enter A
Leave A
Leave B
Enter C
Enter A
Leave A
Leave C
Enter D
Enter A
Leave A
Leave D
Leave E

執行順序很好理解,唯一需要注意的是公共父類A被執行了多次。

代碼二:

復制代碼
class A:  
  def __init__(self):  
    print("Enter A")  
    print("Leave A")  
class B(A):  
  def __init__(self):  
    print("Enter B")  
    super(B, self).__init__()  
    print("Leave B")  
class C(A):  
  def __init__(self):  
    print("Enter C")  
    super(C, self).__init__()  
    print("Leave C")  
class D(A):  
  def __init__(self):  
    print("Enter D")  
    super(D, self).__init__()  
    print("Leave D")  
class E(B, C, D):  
  def __init__(self):  
    print("Enter E")  
    super(E, self).__init__()  
    print("Leave E")  
E()
復制代碼

結果:
Enter E
Enter B
Enter C
Enter D
Enter A
Leave A
Leave D
Leave C
Leave B
Leave E

  在super機制里可以保證公共父類僅被執行一次,至於執行的順序,是按照MRO(Method Resolution Order):方法解析順序 進行的。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM