一. 初識繼承
繼承是一種建立新類的方式,在python中,建立的類可以繼承一個或多個父類,父類又可稱為基類或超類,建立的類稱為派生類或子類.
當我們在定義多個類的時候,發現要用到相同的方法或變量,如果每個類都要寫相同的方法和變量,那麼代碼就會重複,為了減少代碼,可以用繼承來解決.
# 三個類中都有相同的參數,造成代碼重複
class Person:
def __init__(self,name,sex,age):
self.name = name
self.sex = sex
self.age = age
class Cat:
def __init__(self,name,sex,age):
self.name = name
self.sex = sex
self.age = age
class Dog:
def __init__(self,name,sex,age):
self.name = name
self.sex = sex
self.age = age
用繼承的思想來做
class Animal:
animal = '動物'
def __init__(self, name, sex, age):
self.name = name
self.sex = sex
self.age = age
def hobby(self):
print('%s喜歡吃' % self.name)
class Person(Animal): #繼承Animal類
pass
class Cat(Animal):
pass
class Dog(Animal):
pass
print(Person.animal) #動物 類名可以通路父類所有内容
p = Person('jack', '男', 25)
p.hobby() #jack喜歡吃
# 子類以及子類執行個體化的對象 可以通路父類的任何方法或變量.先從本類中找hobby方法,找不到則從父類裡找
既要執行子類的方法,又要執行父類的方法? 有兩種解決方法.
1,Animal.__init__(self, name, sex, age)
2,super().__init__(name,sex,age)
class Animal:
def __init__(self, name, sex, age):
self.name = name
self.sex = sex
self.age = age
def eat(self):
print('%s會吃' % self.name)
def drink(self):
print('%s會喝' % self.name)
class Bird(Animal):
def __init__(self, name, sex, age, wing):
# super().__init__(name, sex, age ) #自動把self傳給父類
Animal.__init__(self, name, sex, age)
self.wing = wing
def egg(self):
print('雞會下蛋')
def eat(self): #本類含有和弗雷相同的方法名
super().drink() #用super()調用父類的方法
print('鳥會吃蟲子')
b = Bird('鳥', '公', 30, '翅膀')
print(b.__dict__) # {'name': '鳥', 'sex': '公', 'age': 30, 'wing': '翅膀'}
b.eat()
# 鳥會喝 #執行父類的eat方法
# 鳥會吃蟲子 #執行本類的eat方法
二. 繼承的進階
1. 單繼承和多繼承
class A:
pass
class B(A): #單繼承
pass
class C(A):
pass
class D(B,C): #多繼承
pass
2. 經典類, 新式類
新式類: 凡是繼承object類都是新式類. python3x 所有的類都是新式類,因為python3x中的類都預設繼承object.
經典類: 不繼承object類都是經典類, python2x:(既有新式類,又有經典類) 所有的類預設都不繼承object類,所有的類預設都是經典類.你可以讓其繼承 object.
單繼承: 新式類,經典類查詢順序一樣.
多繼承繼承順序(讨論的是繼承兩個類):
新式類: 遵循廣度優先 : 一條路走到倒數第二級,判斷,如果其他路能走到終點,則傳回走另一條路.如果不能,則走到終點. 可以用mro()來查詢繼承順序.
經典類: 遵循深度優先 : 一條路走到底.
class A:
def func(self):
print('IN A')
class B(A):
# pass
def func(self):
print('IN B')
class C(A):
# pass
def func(self):
print('IN C')
class D(B):
# pass
def func(self):
print('IN D')
class E(C):
def func(self):
print('IN E')
class F(D,E):
# pass
def func(self):
print('IN F')
f1 = F()
f1.func() #IN F
print(F.mro()) # 查詢類的繼承順序
# [<class '__main__.F'>, <class '__main__.D'>, <class '__main__.B'>, <class '__main__.E'>,
# <class '__main__.C'>, <class '__main__.A'>, <class 'object'>]
3. 多繼承原理: MRO_C算法
mro(): 查詢類的繼承順序. 代碼和步驟如下:
class H:
pass
class G(H):
pass
class F(H):
pass
class E(G):
pass
class D(F):
pass
class C(E):
pass
class B(D):
pass
class A(B, C, D):
pass
print(A.mro())
'''
首先找到A繼承的三個類的深度繼承順序,放到一個清單中
B [B,D,F,H]
C [C,E,G,H]
D [D,F,H]
每個清單的第一個元素為頭部,其它位置元素都為尾部,從第一個清單的頭部開始找,找其他清單中尾部是否含有
這個類名,如果沒有,提取出來放到一個清單中,如果有,找下一個清單的頭部,循環下去
隻要提取來一個,我們就從第一個清單的頭部接着重複上面的操作.
A [A][B,D,F,H] [C,E,G,H] [D,F,H] [B,C,D] A #找到第一個清單的頭A,其他清單尾部沒有A,把A取出來,如果其他清單的頭部有A則剔除
[][B,D,F,H] [C,E,G,H] [D,F,H] [B,C,D] B
[][D,F,H] [C,E,G,H] [D,F,H] [C,D] C
[][D,F,H] [E,G,H] [D,F,H] [D] D
[][F,H] [E,G,H] [F,H] [] F
[][H] [E,G,H] [H] [] E #找到第一個清單的頭部H,但是其他清單尾部有H,是以跳過這個清單,去下一個清單取頭部
[][H] [G,H] [H] [] G
[][H] [H] [H] [] H
[][] [] [] []
lst = [A,B,C,D,F,E,G,H]
'''
class F:
pass
class E:
pass
class D:
pass
class C(D, F):
pass
class B(E, D):
pass
class A(B, C):
pass
print(A.mro())
'''
首先找到A繼承的兩個類的深度繼承順序
把B作為子類,找出B類的查詢順序
B [B] [E] [D] [E,D] B
[] [E] [D] [E,D] E
[] [] [D] [D] D
[] [] [] []
lst = [B,E,D]
把C作為子類,找出C類的查詢順序
C [C] [D] [F] [D,F] C
[] [D] [F] [D,F] D
[] [] [F] [F] F
[] [] [] []
lst = [C,D,F]
A [A] [B,E,D] [C,D,F] [B,C] A
[] [B,E,D] [C,D,F] [B,C] B
[] [E,D] [C,D,F] [C] E
[] [D] [C,D,F] [C] C
[] [D] [D,F] [] D
[] [] [F] [] F
[] [] [] []
lSt = [A,B,E,C,D,F]
'''
轉載于:https://www.cnblogs.com/huangqihui/p/9367520.html