1. 程式人生 > >新式類 VS 經典類

新式類 VS 經典類

.info .com 參數 ood 並不會 類繼承 調用順序 gif its

一、概述

  Python中支持多繼承,也就是一個子類可以繼承多個父類/基類。當一個調用一個自身沒有定義的屬性時,它是按照何種順序去父類中尋找的呢?尤其是當眾多父類中都包含有同名的屬性,這就涉及到新式類 和 經典類的區別。

二、多繼承

技術分享
 1 class Food(object):
 2 
 3     def __init__(self, name, color):
 4         self.name = name
 5         self.color = color
 6 
 7     def eatable(self):
 8         print("%s can be eaten.
" % self.name) 9 10 def appearance(self): 11 print(The color of the %s is %s. % (self.name, self.color)) 12 13 14 class Fruits(object): 15 16 def __init__(self, name, nutrition): 17 self.name = name 18 self.nutrition = nutrition 19 20 def info(self): 21 print
("%s can supply much %s." % (self.name, self.nutrition)) 22 23 24 class Salad(Fruits, Food): # 繼承多個父類 25 26 def __init__(self, name, nutrition, color, tasty): 27 super(Salad, self).__init__(name, nutrition) 28 Food.__init__(self, name, color) 29 self.tasty = tasty 30 31
def taste(self): 32 print("%s is a little %s." % (self.name, self.tasty)) 33 34 35 obj = Salad(orange, VC, orange, sour) 36 37 obj.eatable() 38 obj.appearance() 39 obj.info() 40 obj.taste()
View Code

  上例中的Salad(Fruits,Food)繼承了Fruits和Food兩個父類。

supper()函數為新式類的方法,采用新式類要求最頂層的父類一定要繼承於object,這樣就可以用super()函數來調用父類的init()等函數。每個父類都執行且執行一次,並不會出現重復調用的情況。采用super()方法時,會自動找到第一個多繼承中的第一父類。

  但是如果想要繼續調用其它父類init()函數或兩個父類的同名函數時,就要用經典類的調用方法了,即 父類名.__init__(self,參數),如上例。

三、經典類 VS 新式類的繼承順序

3.1 新式類

1、新式類定義時必須繼承object類,繼承了object類的就叫做 新式類

class Fruits(object):
    ‘新式類‘
    pass

  

2、采用super()函數類調用父類的 init()等函數

super(子類名,self).__init__(參數1,參數2,..)

  

3、調用父類中相同屬性或者方法的順序

新式類的調用順序為: 廣度優先查詢

子類先在自己的所有父類中從左至右查詢,如果沒有需要的方法或屬性,再到本身父類的父類中去查詢。

技術分享

代碼如下:

1.調用本身屬性

技術分享
 1 class A(object):
 2     def __init__(self):
 3         self.n = "A"
 4 
 5 
 6 class B(A):
 7 
 8     def __init__(self):
 9         super(B, self).__init__()
10         self.n = "B"
11 
12 
13 class C(A):
14 
15     def __init__(self):
16         super(C, self).__init__()
17         self.n = "C"
18 
19 
20 class D(B, C):
21 
22     def __init__(self):
23         super(D, self).__init__()
24         self.n = "D"
25 
26 
27 d = D()
28 print(d.n)
29 
30 #輸出
31 D
View Code

2.註釋D中的代碼,獲得B

技術分享
 1 class A(object):
 2     def __init__(self):
 3         self.n = "A"
 4 
 5 
 6 class B(A):
 7 
 8     def __init__(self):
 9         super(B, self).__init__()
10         self.n = "B"
11 
12 
13 class C(A):
14 
15     def __init__(self):
16         super(C, self).__init__()
17         self.n = "C"
18 
19 
20 class D(B, C):
21 
22     # def __init__(self):
23     #     super(D, self).__init__()
24     #     self.n = "D"
25     pass
26 
27 d = D()
28 print(d.n)
29 
30 #輸出
31 B
View Code

3.註釋B中的代碼,獲得C

技術分享
 1 class A(object):
 2     def __init__(self):
 3         self.n = "A"
 4 
 5 
 6 class B(A):
 7 
 8     # def __init__(self):
 9     #     super(B, self).__init__()
10     #     self.n = "B"
11     pass
12 
13 
14 class C(A):
15 
16     def __init__(self):
17         super(C, self).__init__()
18         self.n = "C"
19 
20 
21 class D(B, C):
22 
23     # def __init__(self):
24     #     super(D, self).__init__()
25     #     self.n = "D"
26     pass
27 
28 d = D()
29 print(d.n)
30 
31 #輸出
32 C
View Code

4.註釋C中的代碼,獲得A

技術分享
 1 class A(object):
 2     def __init__(self):
 3         self.n = "A"
 4 
 5 
 6 class B(A):
 7 
 8     # def __init__(self):
 9     #     super(B, self).__init__()
10     #     self.n = "B"
11     pass
12 
13 
14 class C(A):
15     #
16     # def __init__(self):
17     #     super(C, self).__init__()
18     #     self.n = "C"
19     pass
20 
21 
22 class D(B, C):
23 
24     # def __init__(self):
25     #     super(D, self).__init__()
26     #     self.n = "D"
27     pass
28 
29 d = D()
30 print(d.n)
31 
32 #輸出
33 A
View Code

3.2 經典類

1、經典類定義,什麽都不繼承

class Fruit:
    ‘經典類‘
    pass

2、繼承父類的init()等函數或屬性

父類名.__init__(self, 參數1,參數2,....)

  

3、調用父類中相同屬性或者方法的順序

在 Python3 中,多繼承的查詢順序都是 廣度優先查詢

經典類的調用順序為: 深度優先查詢

子類會沿著父類的父類這樣的順序查詢,如果都沒有,會返回查找另一個父類。

技術分享

代碼如下:

1.調用本身的屬性

技術分享
 1 class A:#經典類
 2     def __init__(self):
 3         self.n = "A"
 4 
 5 class B(A):
 6     pass
 7     def __init__(self):
 8         self.n = "B"
 9 
10 class C(A):
11     def __init__(self):
12         self.n = "C"
13 
14 class D(B,C):
15     def __init__(self):
16         self.n = "D"
17 
18 d = D()
19 print(d.n)
20 
21 #輸出
22 D
23 
24 全部代碼
View Code

2. 註釋D中的代碼,獲得B

技術分享
 1 class A:
 2     def __init__(self):
 3         self.n = "A"
 4 
 5 class B(A):
 6     def __init__(self):
 7         self.n = "B"
 8 
 9 class C(A):
10     def __init__(self):
11         self.n = "C"
12 
13 class D(B,C):
14     pass
15 
16 d = D()
17 print(d.n)
18 
19 #輸出
20 B
View Code

3.註釋B中的代碼,獲得A

技術分享
 1 class A:
 2     def __init__(self):
 3         self.n = "A"
 4 
 5 class B(A):
 6     pass
 7 
 8 class C(A):
 9     def __init__(self):
10         self.n = "C"
11 
12 class D(B,C):
13     pass
14 
15 d = D()
16 print(d.n)
17 
18 #輸出
19 A
View Code

4.註釋A中的代碼,獲得C

技術分享
 1 class A:
 2     pass
 3 
 4 class B(A):
 5     pass
 6 
 7 class C(A):
 8     def __init__(self):
 9         self.n = "C"
10 
11 class D(B,C):
12     pass
13 
14 d = D()
15 print(d.n)
16 
17 #輸出
18 C
View Code

四、總結

1、新式類繼承object類,經典類不繼承任何類

2、新式類用super關鍵字繼承構造方法,經典類用 父類.__init(self)來繼承

3、新式類:廣度優先查詢,經典類:深度優先查詢(因為新式類講究的是新,所以要找最近的,最新的;然後經典的講究古老,所以更遠更深的)

4、值得註意的是,我們上面是在python2中做的,在python3中不管是經典類還是新式類,都是采用的是廣度優先查詢,已經廢棄2中的深度查詢了

新式類 VS 經典類