Python()- 面向對象三大特性----繼承
繼承:
繼承是一種創建新類的方式,
在python中,新建的類可以繼承一個或多個父類(基類或超類),新建的類是所繼承的類的(派生類或子類)
人類和狗 有相同的屬性, 提取了一個__init__方法,在這個方法裏放一些共有的屬性
人類和狗 在相同的方法,提取了一個def func():方法,在這個方法裏放一些共有的方法
單繼承和多繼承
class Par1: pass class Par2: pass class Sub1(Par1): pass class Sub2(Par1,Par2): pass #__base__只查看從左到右的第一個父類,而__bases__查看所有父類 print(Sub1.__bases__) #(<class ‘__main__.Par1‘>,) print(Sub2.__bases__) #(<class ‘__main__.Par1‘>, <class ‘__main__.Par2‘>) ------------------------------------ print(Par1.__base__) #<class ‘object‘>
如果沒有指定基類,python的類默認繼承object類,object類是所有類的基類,它提供了一些常見的方法(如__str__)的實現
class Par1: def __init__(self,name): self.name = name def __str__(self): return self.name p = Par1(‘kitty‘) print(p) # kitty
class Foo1: def __init__(self,name): # self是f對象 self.name = name def __str__(self): return self.name class Foo2(Foo1): a = 1 f = Foo2(‘kitty‘) #Foo2中沒有__init__函數,就去基類去找,然後傳入參數 print(f.name) # kitty
繼承與抽象:
世間本來沒有人類,只是很多個具體的人對象,後來把所有的人抽象成(劃規成)一類,才有了人類的概念
so: 抽象是從下往上
繼承從上往下
繼承與重用性:
繼承的目的是為了減少代碼的重復性
比如:
想創建一個b類, 但是發現b類的屬性大部分和a類的相同, 就讓b去繼承a的屬性,節省代碼
提示:用已經有的類建立一個新的類,這樣就重用了已經有的軟件中的一部分設置大部分,大大生了編程工作量,這就是常說的軟件重用,不僅可以重用自己的類,也可以繼承別人的,比如標準庫,來定制新的數據類型,這樣就是大大縮短了軟件開發周期,對大型軟件開發來說,意義重大.
經典類 和 新式類:
python3都是新式類 (新式類默認繼承object class Foo(object): == class Foo: )
python2中經典類和新式類共存
- class Foo: 是經典類
- class Foo(object): 是新式類
鉆石繼承:
- 經典類: 深度優先,就是單線走到頭,再去其它線
- 新式類: 就是單線走到剩余最後一個父類停止,再去找其它線,最後一條線走到尾
經典類繼承順序:
深度優先
新式類繼承順序:
廣度優先:
如果找到b就去找c c再去找e e在去找f f沒有就報錯了 因為f找不到d 單線
=====================================================
python2 中: 最原始的加上object,往後的都會繼承object
======================================
再來看:
class D: def __init__(self): print(‘d‘) class C(D): def __init__(self): print(‘c‘) super().__init__() class B(D): def __init__(self): print(‘b‘) super().__init__() class A(B,C): def __init__(self): print(‘a‘) super().__init__() #mro a = A() print(A.mro()) ##結果如下: a b c d [<class ‘__main__.A‘>, <class ‘__main__.B‘>, <class ‘__main__.C‘>, <class ‘__main__.D‘>, <class ‘object‘>] 和mro的順序一樣 廣度優先 (super只有新式類中有) 在多繼承中,super不只是尋找當前類的父類,而是依據mro順序, 從A節點出發,根據廣度優先排序查找下一個類
派生
派生:
class A: # 基類(提取了狗和人的共同屬性) def __init__(self,name, aggressivity, life_value): #裏面的self是對象 self.name = name self.aggressivity = aggressivity self.life_value = life_value def eat(self): print(‘A eating‘) class Dog(A): # 定義一個狗類 def __init__(self,name, aggressivity, life_value,breed,): #派生一個__init__方法 #A.__init__(self,name, aggressivity, life_value) : 類名.__init__(參數) super().__init__(name, aggressivity, life_value) #調用基類__init__方法:super().__init__() self.breed = breed # 每一只狗都有自己的品種; def bite(self,people): #派生bite方法 父類中沒有的屬性&方法 people.life_value -= self.aggressivity def eat(self): #重新定義eat (派生) A.eat(self) #如果想加上父類的方法: A.eat(對象) print(‘dog eating‘) class Person(A): # 定義一個人類 def __init__(self,name, aggressivity, life_value,money): #派生 super().__init__(name, aggressivity, life_value) #調用基類__init__方法 self.money = money def attack(self,dog): dog.life_value -= self.aggressivity def get_weapon(self,weapon_obj): if self.money > weapon_obj.price: self.money -= weapon_obj.price # 金老板花錢買武器 self.weapon = weapon_obj # 金老板裝備打狗棒 self.aggressivity += weapon_obj.aggr # 金老板的攻擊力增加了 jin = Person(‘jin‘,250,250,100) dog = Dog(‘酷狗‘,33,50,‘藏獒‘) print(jin.name) # jin print(jin.money) # 100 print(dog.name) # 酷狗 print(dog.breed) # 藏獒 dog.eat() # A eating # dog eating ------------------- A.eat(dog) #A eating 類名.方法名(對象名) -------------------------------- super(Dog,dog).eat() #A eating super(類名,對象名) super在外面用,必須傳參數 ========================================
派生方法和屬性:
1.在子類中增加父類沒有的
2.如果再調用父類的的方法和屬性
父類.__init__(self,參數...)
super()__init__(參數...) ? 指名道姓調用
在類外面用super的時候, super(子類名,對象).屬性
小結:
子類有,用自己的,沒有用父類的
子類有,父類有,仍然想用父類的:
經典類: 父類.__init__(self,參數...) 父類.方法名(對象)
新式類: super().__init__(參數...) 父類.方法名(對象)
一般情況下super都滿足了
指名道姓調用父類的方法 父類.方法(self) self是子類的對象
例題:打印結果
class Foo: def __init__(self): (self是對象,對象自己有func()) self.func() def func(self): print(‘父類‘) class Son(Foo): def func(self): print(‘子類‘) s = Son() #子類 ---------------- print(Son.mro()) 新式類才有的查看繼承順序的方法: print(類名.mro()) [<class ‘__main__.Son‘>, <class ‘__main__.Foo‘>, <class ‘object‘>]
Python()- 面向對象三大特性----繼承