002.python 多繼承呼叫指定父類同名方法的方法
阿新 • • 發佈:2021-01-13
技術標籤:Python全棧
如果子類和繼承了多個父類,並且這些父類中有多個方法的方法名一樣時,我該如何呼叫指定父類中的同名方法呢?不妨先舉一個小例子:
class A:
def f_a(self):
print('--------A--------')
class B:
def f_a(self):
print('-------B-------')
class C(A,B):
def f_a(self):
print('--------C--------')
c = C()
c.f_a()
>>> -- ------C--------
如果我們想在C類中的f_a方法裡面使用父類A或者父類B的方法該如何操作呢?
方法有兩種:
方法一:把物件呼叫轉換為類呼叫:
class C(A,B):
def f_a(self):
A.f_a(self)
B.f_a(self)
print('--------C--------')
c = C()
c.f_a()
輸出結果為:
>>>--------A--------
>>>--------B--------
>>>--------C--------
這裡呼叫父類的f_a方法時括號裡面要寫self,表明這是一個類呼叫,但這種方法有一個缺點,比如說如果修改了父類的名稱,那麼在子類中會涉及多出修改,並且python是允許多繼承的語言,上述方法在多繼承時就要重複寫多次,顯得累贅,為了解決這些問題,python引進了super()機制,接下來想必大家都猜到了下一種呼叫父類的另一種方法了吧。
方法二:使用super()機制,引入super()方法:
class C(A,B):
def f_a(self):
super().f_a()
print('--------C--------')
c = C()
c. f_a()
>>>--------A--------
>>>--------C--------
這裡直接使用super()方法會呼叫A類的f_a方法,因為它會預設多繼承中從左到右的順序來呼叫,那麼有人就會問了,假如我想呼叫B類中的f_a方法是不是把A和B對調下呢,這種方法也行,不過這不算的上是一種較為巧妙的方法。
我們還可以使用super()方法,但要對其修改下:
class C(A,B):
def f_a(self):
super(C,self).f_a()
super(A,self).f_a()
print('--------C--------')
c = C()
c.f_a()
>>>--------A--------
>>>--------B--------
>>>--------C--------
看到沒,這樣寫:super(C,self).f_a()會呼叫最左邊的(即A類)的f_a方法,而super(A,self).f_a()會呼叫A類後面那個類的f_a()方法,若果繼承的不止兩個類,如果要呼叫某個類方法,只要知道前一個類名就可以呼叫。
下面給出一個例子,請讀者自行思考執行結果:
class Point(object):
def __init__(self,x,y):
self.x = x
self.y = y
def string(self):
print("X:{0},Y:{1}".format(self.x,self.y))
# class Circle(Point):
#
# def __init__(self,x,y,radius):
# super().__init__(x,y)
# self.radius = radius
#
# def string(self):
# print("該圖形初始化點為:({0},{1}),半徑為:{2}。".format(self.x,self.y,self.radius))
class Size:
def __init__(self,width,heigth):
self.width = width
self.height = heigth
def string(self):
print("Width:{0},Height:{1}".format(self.width,self.height))
class Rectangle(Point,Size):
def __init__(self,x,y,width,height):
super(Rectangle,self).__init__(x,y)
super(Point,self).__init__(width,height)
#這裡值得注意的是,如果要跨過一個父類去另外一個父類呼叫同名方法時
#應當在super()的引數中指定要繼承的類在繼承順序中的前一個類的名稱
#如果沒有就把這個名稱寫成自己的類名
def string(self):
print("該圖形的初始化點為({0},{1}),長寬分別為Height:{2},Width:{3}".format(self.x,self.y,self.height,self.width))
if __name__ == '__main__':
# c = Circle(0,0,100)
# c.string()
r = Rectangle(0,0,100,100)
r.string()