繼承指的是類與類之間的關係,繼承的功能之一就是能夠用來解決代碼重用問題。python
(1)繼承是一種建立新類的方式編程
(2)在python中,新建的類能夠繼承一個或多個父類(其餘語言只能繼承一個父類),父類又能夠稱爲基類或者超類數據結構
(3)新建的類稱爲派生類或子類。編程語言
class ParentClass1: pass class ParentClass2: pass class SubClass1(ParentClass1): # 單繼承,基類是ParentClass1,派生類是SubClass pass class SubClass2(ParentClass1, ParentClass2): # 多繼承,用逗號分隔開多個繼承的類 pass
__base__:只查看從左到右繼承的第一個子類
__bases__:查看全部繼承的父類ide
print(ParentClass1.__base__, type(ParentClass1.__base__)) print(SubClass1.__base__, type(SubClass1.__base__)) print(SubClass2.__base__, type(SubClass2.__base__)) # 只查看到第一個父類 """ <class 'object'> <class 'type'> <class '__main__.ParentClass1'> <class 'type'> <class '__main__.ParentClass1'> <class 'type'> """ print(SubClass1.__bases__) print(SubClass2.__bases__) """數據結構爲元組 (<class '__main__.ParentClass1'>,) (<class '__main__.ParentClass1'>, <class '__main__.ParentClass2'>) """
(1)python2中的經典類和新式類函數
經典類:沒有顯式繼承object類的類,以及該類的子類都是經典類。spa
新式類:顯式地聲明繼承object類,以及該類的子類都是新式類。設計
# Python2中經典類:沒有繼承object的類,以及它的子類 class Foo: pass class Bar(Foo): pass # python2中新式類:繼承object的類,以及它的子類都稱爲新式類 class Foo(object): pass class Bar(Foo): pass """ >>> class Foo:pass ... >>> Foo.__bases__ () >>> class Foo(object):pass ... >>> Foo.__bases__ (<type 'object''>,) """
僅在python2中才分新式類和經典類,在python3中,不管是否繼承object,都默認繼承object,即python3中全部類均爲新式類。
code
提示:若是沒有指定基類,python的類會默認繼承object類,object是全部python類的基類,它提供了一些常見方法(如__str__)的實現。對象
# python3中新式類:一個類沒有繼承object類,默認就繼承object class Foo(): pass print(Foo.__bases__) # (<class 'object'>,)
繼承描述的是子類與父類之間的關係,是一種什麼是什麼的關係。要找出這種關係,必須先抽象再繼承。
抽象定義即抽取相似或者說比較像的部分(也就是提取一類事物的特色,範圍愈來愈大,共性愈來愈少)。
抽象分爲兩個層次:
(1)將奧巴馬和梅西這倆對象比較像的部分抽取成類;
(2)將人,豬,狗這三個類比較像的部分抽取成父類。
抽象最主要的做用是劃分類別(能夠隔離關注點,下降複雜度)
繼承:是基於抽象的結果,經過編程語言去實現它,確定是先經歷抽象這個過程,才能經過繼承的方式去表達出抽象的結構。
抽象:只是分析和設計的過程當中,一個動做或者說一種技巧,經過抽象能夠獲得類。
class Hero: def __init__(self, nickname, life_value, aggresivity): self.nickname = nickname self.life_value = life_value self.aggresivity = aggresivity def attack(self, enemy): enemy.life_value -= self.aggresivity class Garen(Hero): pass class Riven(Hero): pass g1 = Garen('剛哥', 29, 30) print(g1.__dict__) """ {'nickname': '剛哥', 'life_value': 29, 'aggresivity': 30} """
開發程序的過程當中,若是咱們定義了一個類A,而後又想新創建另一個類B,可是類B的大部份內容與類A的相同時:
能夠經過繼承的方式新建類B,讓B繼承A,B會‘遺傳’A的全部屬性(數據屬性和函數屬性),實現代碼重用。
class Hero: def __init__(self,nickname,aggressivity,life_value): self.nickname=nickname self.aggressivity=aggressivity self.life_value=life_value def move_forward(self): print('%s move forward' %self.nickname) def move_backward(self): print('%s move backward' %self.nickname) def move_left(self): print('%s move forward' %self.nickname) def move_right(self): print('%s move forward' %self.nickname) def attack(self,enemy): enemy.life_value-=self.aggressivity class Garen(Hero): pass class Riven(Hero): pass g1=Garen('草叢倫',100,300) r1=Riven('銳雯雯',57,200) print(g1.life_value) #結果:300 r1.attack(g1) print(g1.life_value) #結果:243
用已經有的類創建一個新的類,這樣就重用了已經有的軟件中的一部分設置大部分,大大節省了編程工做量,這就是常說的軟件重用,不只能夠重用本身的類,也能夠繼承別人的,好比標準庫,來定製新的數據類型,這樣就是大大縮短了軟件開發週期,對大型軟件開發來講,意義重大.
子類有本身的方法,就執行本身的;若是子類沒有本身的方法,就會找父類的。
class Foo: def f1(self): print('from Foo.f1') def f2(self): print('from Foo.f2') self.f1() class Bar(Foo): def f2(self): print('from Bar.f2') b = Bar() print(b.__dict__) # 未定義__init__沒有本身的屬性 字典內爲空 b.f1() # 指向父類的函數 b.f2() # 指向子類重用的函數 """ {} from Foo.f1 from Bar.f2 # 注意和父類中的區別 """
在父類的基礎上產生子類,產生的子類就叫作派生類
父類裏有,子類也有的方法,就叫作方法的重寫(就是把父類裏的方法重寫)
class Riven(Hero): camp='Noxus' def attack(self,enemy): #在本身這裏定義新的attack,再也不使用父類的attack,且不會影響父類 print('from riven') def fly(self): #在本身這裏定義新的 print('%s is flying' %self.nickname)
父類裏沒有的方法,在子類中有了,這樣的方法就叫作派生方法。
class Riven(Hero): camp='Noxus' def __init__(self,nickname,aggressivity,life_value,skin): Hero.__init__(self,nickname,aggressivity,life_value) #調用父類功能 self.skin=skin #新屬性 def attack(self,enemy): #在本身這裏定義新的attack,再也不使用父類的attack,且不會影響父類 Hero.attack(self,enemy) #調用功能 print('from riven') def fly(self): #在本身這裏定義新的 print('%s is flying' %self.nickname) r1=Riven('銳雯雯',57,200,'比基尼') r1.fly() print(r1.skin) ''' 運行結果 銳雯雯 is flying 比基尼 '''