自學Python之路-Python基礎+模塊+面向對象
自學Python之路-Python網絡編程
自學Python之路-Python併發編程+數據庫+前端
自學Python之路-djangohtml
1、初始繼承(單繼承)前端
繼承是指這樣一種能力:它可使用現有類的全部功能,並在無需從新編寫原來的類的狀況下對這些功能進行擴展。python
class A(object):pass # 父類,基類,超類 class B:pass # 父類,基類,超類 class A_son(A,B):pass # 子類,派生類 class AB_son(A):pass # 子類,派生類
沒有繼承父類,默認繼承object 。數據庫
抽象即抽取相似或者說比較像的部分。
抽象最主要的做用是劃分類別(能夠隔離關注點,下降複雜度)。django
繼承:是基於抽象的結果,經過編程語言去實現它,確定先經歷抽象這個過程,才能經過繼承的方式去表達出抽象的結構。編程
抽象只是分析和設計的過程當中,一個動做或者說一種技巧,經過抽象能夠獲得類。網絡
# 好比舉例人狗大戰。 如下有兩個類,你會發現兩個類有共同點 class Dog: def __init__(self,name,aggr,hp): self.name = name self.aggr = aggr self.hp = hp def bitc(self,person): person.hp -= self.aggr class person: def __init__(self,name,aggr,hp,sex): self.name = name self.aggr = aggr self.hp = hp self.sex = sex self.money = 0 def attack(self,dog): person.hp -= self.aggr def get_weapon(self,weapon): if self.money >= weapon.price: self.money -= weapon.price self.get_weapon = weapon self.aggr += weapon.aggr else: print("餘額不足,請先充值")
將以上兩個類相同的地方建立一個新的類, 兩個類在繼承新的類。併發
class Animal: def __init__(self,name,aggr,hp): self.name = name #人和狗都有本身的暱稱 self.aggr = aggr #人和狗都有本身的攻擊力 self.hp = hp #人和狗都有本身的生命值 class Dog(Animal): def bitc(self,person): person.hp -= self.aggr class person(Animal): pass Liu = Dog("劉老闆",200,500) print(Liu.name)
舉個例子:python2.7
一個狗類: 吃、喝、看門編程語言
一個鳥類: 吃、喝、下單
class Animal: def __init__(self): print('執行Animal.__init__') self.func() def eat(self): print('%s eating'%self.name) def drink(self): print('%s drinking'%self.name) def func(self): print('Animal.func') class Dog(Animal): def guard(self): print('guarding') def func(self): print('Dog.func') class Bird(Animal): def __init__(self,name): self.name = name def lay(self): print('laying')
好比定義一個實例 dog = Dog(),其中產生了一個問題
當執行Dog類的時候,Dog類沒有__init__(self)就執行父類Animal的__init__(self),而後執行了self.func(),此時Animal和Dog類同時擁有self.func(),那麼它執行哪一個類的self.func()? 答案是:Dog的self.func()
提示:
用已經有的類創建一個新的類,這樣就重用了已經有的軟件中的一部分設置大部分,大大生了編程工做量,這就是常說的軟件重用,不只能夠重用本身的類,也能夠繼承別人的,好比標準庫,來定製新的數據類型,這樣就是大大縮短了軟件開發週期,對大型軟件開發來講,意義重大。
固然子類也能夠添加本身新的屬性或者在本身這裏從新定義這些屬性(不會影響到父類),須要注意的是,一旦從新定義了本身的屬性且與父類重名,那麼調用新增的屬性時,就以本身爲準了。
# 好比接上面的舉例。 class Animal: def __init__(self,name,aggr,hp): self.name = name self.aggr = aggr self.hp = hp class Dog(Animal): def __init__(self,name,aggr,hp,kind): self.kind = kind def bitc(self,person): person.hp -= self.aggr Liu = Dog("劉老闆",20,500,"吉娃娃") print(Liu.name) # 報錯,由於只執行Dog類裏面的_init_,可是裏面沒有name
class Animal: def __init__(self,name,aggr,hp): self.name = name self.aggr = aggr self.hp = hp def eat(self): print('吃藥回血') self.hp+=100 class Dog(Animal): def __init__(self,name,aggr,hp,kind): Animal.__init__(self,name,aggr,hp) # self.kind = kind # 派生屬性(父類沒有的,子類新增的屬性) class Person(Animal): def __init__(self,name,aggr,hp,sex): Animal.__init__(self,name,aggr,hp) self.sex = sex # 派生屬性 self.money = 0 # 派生屬性 Liu = Dog('劉老闆',20,500,'吉娃娃') Liu.eat() #使用的繼承父類animal的eat方法 print(Liu.hp) tong = Person('tong',1,2,None) tong.eat() #使用的繼承父類animal的eat方法 print(tong.hp)
class Animal: def __init__(self,name,aggr,hp): self.name = name self.aggr = aggr self.hp = hp def eat(self): print('吃藥回血') self.hp+=100 class Dog(Animal): def __init__(self,name,aggr,hp,kind): Animal.__init__(self,name,aggr,hp) # self.kind = kind # 派生屬性(父類沒有的,子類有的屬性) def bite(self,person): # 派生方法(父類沒有的,子類有的方法) person.hp -= self.aggr class Person(Animal): def __init__(self,name,aggr,hp,sex): Animal.__init__(self,name,aggr,hp) self.sex = sex # 派生屬性 self.money = 0 # 派生屬性 def attack(self,dog): dog.hp -= self.aggr def get_weapon(self,weapon): if self.money >= weapon.price: self.money -= weapon.price self.weapon = weapon self.aggr += weapon.aggr else: print("餘額不足,請先充值") Liu = Dog('劉老闆',20,500,'吉娃娃') Liu.eat() #使用的繼承父類animal的eat方法 print(Liu.hp) tong = Person('tong',1,2,None) tong.eat() #使用的繼承父類animal的eat方法 print(tong.hp) Liu.bite(tong) #使用Dog類本身的派生方法 print(tong.hp)
在子類中,新建的重名的函數屬性,在編輯函數內功能的時候,有可能須要重用父類中重名的那個函數功能,應該是用調用普通函數的方式,即:類名.func(),此時就與調用普通函數無異了,所以即使是self參數也要爲其傳值.
在python3中,子類執行父類的方法也能夠直接用super方法。
class A: def hahaha(self): print('A') class B(A): def hahaha(self): super().hahaha() #super(B,self).hahaha() #A.hahaha(self) print('B') a = A() b = B() b.hahaha() super(B,b).hahaha()
總結:
class Animal: def __init__(self,name,aggr,hp): self.name = name self.aggr = aggr self.hp = hp def eat(self): print('吃藥回血') self.hp+=100 class Dog(Animal): def __init__(self,name,aggr,hp,kind): super().__init__(name,aggr,hp) #等價於Animal.__init__(self,name,aggr,hp),不須要傳self self.kind = kind # 派生屬性(父類沒有的,子類新增的屬性) Liu = Dog('劉老闆',20,500,'吉娃娃') Liu.eat() #使用的繼承父類animal的eat方法 print(Liu.hp)
super()能夠在類內使用,也能夠在類外使用。
#super()在類外和類內 class Animal: def __init__(self,name,aggr,hp): self.name = name self.aggr = aggr self.hp = hp def eat(self): print('吃藥回血') self.hp+=100 class Dog(Animal): def __init__(self,name,aggr,hp,kind): super().__init__(name,aggr,hp) #等價於Animal.__init__(self,name,aggr,hp) self.kind = kind # 派生屬性(父類沒有的,子類新增的屬性) def eat(self):print("dog eating") Liu = Dog('劉老闆',20,500,'吉娃娃') print(Liu.name) Liu.eat() # 執行的是Dog類裏面的def eat(self):print("dog eating") super(Dog,Liu).eat() # 執行的是父類裏面的def eat(self):
class A: def func(self):print("A") class B: def func(self):print("B") class C: def func(self):print("C") class D(A,B,C): # D類繼承A,B,C,多繼承 def func(self):print("D") d = D() d.func() #此時調用的D類的func()
class A: def func(self):print("A") class B: def func(self):print("B") class C: def func(self):print("C") class D(A,B,C): # D類繼承A,B,C,多繼承 pass #def func(self):print("D") d = D() d.func() #此時調用的A類的func(),由於class D(A,B,C),A類離D最近
B、C繼承A,D繼承B、C
class A: def func(self):print("A") class B(A): # B類繼承A def func(self):print("B") class C(A): # C類繼承A def func(self):print("C") class D(B,C): # D類繼承B,C pass #def func(self):print("D") d = D() d.func()
class A: def func(self):print("A") class B(A): # B類繼承A pass #def func(self):print("B") class C(A): # C類繼承A def func(self):print("C") class D(B,C): # D類繼承B,C pass #def func(self):print("D") d = D() d.func()
class A: def func(self):print("A") class B(A): # B類繼承A pass #def func(self):print("B") class C(A): # C類繼承A pass #def func(self):print("C") class D(B,C): # D類繼承B,C pass #def func(self):print("D") d = D() d.func()
同理如下兩個問題,繼承順序以下圖:
多繼承中,咱們子類的對象調用一個方法,默認是就近原則,找的順序是什麼?
① python2.7 新式類和經典類共存,新式類要繼承object
② python3 只有新式類,默認繼承object
③ 經典類和新式類還有一個區別:mro方法只在新式類中存在,類名.mro方法,查看廣度優先的繼承順序。
④ super 只在python3中存在
⑤ super的本質 :不是單純找父類 而是根據調用者的節點位置的廣度優先順序來的
class A(object): def func(self): print('A') class B(A): def func(self): super().func() print('B') class C(A): def func(self): super().func() print('C') class D(B,C): def func(self): super().func() print('D') b = D() b.func()
......