python3 類的繼承
1.繼承的定義
繼承是一種創建新類的方式,在python中,新建的類可以繼承一個或多個父類,父類又可稱為基類或超類,新建的類稱為派生類或子類。
2.單繼承和多繼承
class ParentClass1: #定義父類
pass
class ParentClass2: #定義父類
pass
class SubClass1(ParentClass1): #單繼承,基類是ParentClass1,派生類是SubClass
pass
class SubClass2(ParentClass1,ParentClass2): #python支持多繼承,用逗號分隔開多個繼承的類
pass
查看繼承
>>> SubClass1.__bases__ #__base__只查看從左到右繼承的第一個子類,__bases__則是查看所有繼承的父類
(<class ‘__main__.ParentClass1‘>,)
>>> SubClass2.__bases__
(<class ‘__main__.ParentClass1‘>, <class ‘__main__.ParentClass2‘>)
提示:如果沒有指定基類,python的類會默認繼承object類,object是所有python類的基類,它提供了一些常見方法(如__str__)的實現。
>>> ParentClass1.__bases__
(<class ‘object‘>,)
>>> ParentClass2.__bases__
(<class ‘object‘>,)
3.繼承與抽象(先抽象再繼承)
抽象即抽取類似或者說比較像的部分。
抽象分成兩個層次:
1.將奧巴馬和梅西這倆對象比較像的部分抽取成類;
2.將人,豬,狗這三個類比較像的部分抽取成父類。
抽象最主要的作用是劃分類別(可以隔離關註點,降低復雜度)
繼承:是基於抽象的結果,通過編程語言去實現它,肯定是先經歷抽象這個過程,才能通過繼承的方式去表達出抽象的結構。
抽象只是分析和設計的過程中,一個動作或者說一種技巧,通過抽象可以得到類
4.繼承與重用性
復制代碼
==========================第一部分
例如
貓可以:喵喵叫、吃、喝、拉、撒
狗可以:汪汪叫、吃、喝、拉、撒
如果我們要分別為貓和狗創建一個類,那麽就需要為 貓 和 狗 實現他們所有的功能,偽代碼如下:
#貓和狗有大量相同的內容
class 貓:
def 喵喵叫(self):
print ‘喵喵叫‘
def 吃(self):
# do something
def 喝(self):
# do something
def 拉(self):
# do something
def 撒(self):
# do something
class 狗:
def 汪汪叫(self):
print ‘汪汪叫‘
def 吃(self):
# do something
def 喝(self):
# do something
def 拉(self):
# do something
def 撒(self):
# do something
==========================第二部分
上述代碼不難看出,吃、喝、拉、撒是貓和狗都具有的功能,而我們卻分別的貓和狗的類中編寫了兩次。如果使用 繼承 的思想,如下實現:
動物:吃、喝、拉、撒
貓:喵喵叫(貓繼承動物的功能)
狗:汪汪叫(狗繼承動物的功能)
偽代碼如下:
class 動物:
def 吃(self):
# do something
def 喝(self):
# do something
def 拉(self):
# do something
def 撒(self):
# do something
# 在類後面括號中寫入另外一個類名,表示當前類繼承另外一個類
class 貓(動物):
def 喵喵叫(self):
print ‘喵喵叫‘
# 在類後面括號中寫入另外一個類名,表示當前類繼承另外一個類
class 狗(動物):
def 汪汪叫(self):
print ‘汪汪叫‘
==========================第三部分
#繼承的代碼實現
class Animal:
def eat(self):
print("%s 吃 " %self.name)
def drink(self):
print ("%s 喝 " %self.name)
def shit(self):
print ("%s 拉 " %self.name)
def pee(self):
print ("%s 撒 " %self.name)
class Cat(Animal):
def __init__(self, name):
self.name = name
self.breed = ‘貓‘
def cry(self):
print(‘喵喵叫‘)
class Dog(Animal):
def __init__(self, name):
self.name = name
self.breed=‘狗‘
def cry(self):
print(‘汪汪叫‘)
# ######### 執行 #########
c1 = Cat(‘小白家的小黑貓‘)
c1.eat()
c2 = Cat(‘小黑的小白貓‘)
c2.drink()
d1 = Dog(‘胖子家的小瘦狗‘)
d1.eat()
使用繼承來重用代碼比較好的例子
繼承與重用性
在開發程序的過程中,如果我們定義了一個類A,然後又想新建立另外一個類B,但是類B的大部分內容與類A的相同時
我們不可能從頭開始寫一個類B,這就用到了類的繼承的概念。
通過繼承的方式新建類B,讓B繼承A,B會‘遺傳’A的所有屬性(數據屬性和函數屬性),實現代碼重用
class Animal:
‘‘‘
人和狗都是動物,所以創造一個Animal基類
‘‘‘
def __init__(self, name, aggressivity, life_value):
self.name = name # 人和狗都有自己的昵稱;
self.aggressivity = aggressivity # 人和狗都有自己的攻擊力;
self.life_value = life_value # 人和狗都有自己的生命值;
def eat(self):
print(‘%s is eating‘%self.name)
class Dog(Animal):
pass
class Person(Animal):
pass
egg = Person(‘egon‘,10,1000)
ha2 = Dog(‘二楞子‘,50,1000)
egg.eat()
ha2.eat()
提示:用已經有的類建立一個新的類,這樣就重用了已經有的軟件中的一部分設置大部分,大大生了編程工作量,這就是常說的軟件重用,不僅可以重用自己的類,也可以繼承別人的,比如標準庫,來定制新的數據類型,這樣就是大大縮短了軟件開發周期,對大型軟件開發來說,意義重大。
5.類的派生
當然子類也可以添加自己新的屬性或者在自己這裏重新定義這些屬性(不會影響到父類),需要註意的是,一旦重新定義了自己的屬性且與父類重名,那麽調用新增的屬性時,就以自己為準了。
class Animal:
‘‘‘
人和狗都是動物,所以創造一個Animal基類
‘‘‘
def __init__(self, name, aggressivity, life_value):
self.name = name # 人和狗都有自己的昵稱;
self.aggressivity = aggressivity # 人和狗都有自己的攻擊力;
self.life_value = life_value # 人和狗都有自己的生命值;
def eat(self):
print(‘%s is eating‘%self.name)
class Dog(Animal):
‘‘‘
狗類,繼承Animal類
‘‘‘
def bite(self, people):
‘‘‘
派生:狗有咬人的技能
:param people:
‘‘‘
people.life_value -= self.aggressivity
class Person(Animal):
‘‘‘
人類,繼承Animal
‘‘‘
def attack(self, dog):
‘‘‘
派生:人有攻擊的技能
:param dog:
‘‘‘
dog.life_value -= self.aggressivity
egg = Person(‘egon‘,10,1000)
ha2 = Dog(‘二楞子‘,50,1000)
print(ha2.life_value)
print(egg.attack(ha2))
print(ha2.life_value)
註意:像ha2.life_value之類的屬性引用,會先從實例中找life_value然後去類中找,然後再去父類中找...直到最頂級的父類。
在子類中,新建的重名的函數屬性,在編輯函數內功能的時候,有可能需要重用父類中重名的那個函數功能,應該是用調用普通函數的方式,即:類名.func(),此時就與調用普通函數無異了,因此即便是self參數也要為其傳值.
在python3中,子類執行父類的方法也可以直接用super方法.
(1)supper
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()
(2)人狗大戰
class Animal:
‘‘‘
人和狗都是動物,所以創造一個Animal基類
‘‘‘
def __init__(self, name, aggressivity, life_value):
self.name = name # 人和狗都有自己的昵稱;
self.aggressivity = aggressivity # 人和狗都有自己的攻擊力;
self.life_value = life_value # 人和狗都有自己的生命值;
def eat(self):
print(‘%s is eating‘%self.name)
class Dog(Animal):
‘‘‘
狗類,繼承Animal類
‘‘‘
def __init__(self,name,breed,aggressivity,life_value):
super().__init__(name, aggressivity, life_value) #執行父類Animal的init方法
self.breed = breed #派生出了新的屬性
def bite(self, people):
‘‘‘
派生出了新的技能:狗有咬人的技能
:param people:
‘‘‘
people.life_value -= self.aggressivity
def eat(self):
# Animal.eat(self)
#super().eat()
print(‘from Dog‘)
class Person(Animal):
‘‘‘
人類,繼承Animal
‘‘‘
def __init__(self,name,aggressivity, life_value,money):
#Animal.__init__(self, name, aggressivity, life_value)
#super(Person, self).__init__(name, aggressivity, life_value)
super().__init__(name,aggressivity, life_value) #執行父類的init方法
self.money = money #派生出了新的屬性
def attack(self, dog):
‘‘‘
派生出了新的技能:人有攻擊的技能
:param dog:
‘‘‘
dog.life_value -= self.aggressivity
def eat(self):
#super().eat()
Animal.eat(self)
print(‘from Person‘)
egg = Person(‘egon‘,10,1000,600)
ha2 = Dog(‘二楞子‘,‘哈士奇‘,10,1000)
print(egg.name)
print(ha2.name)
egg.eat()
通過繼承建立了派生類與基類之間的關系,它是一種‘是‘的關系,比如白馬是馬,人是動物。
當類之間有很多相同的功能,提取這些共同的功能做成基類,用繼承比較好,比如教授是老師。
>>> class Teacher:
... def __init__(self,name,gender):
... self.name=name
... self.gender=gender
... def teach(self):
... print(‘teaching‘)
...
>>>
>>> class Professor(Teacher):
... pass
...
>>> p1=Professor(‘egon‘,‘male‘)
>>> p1.teach()
teaching
復制代碼
python3 類的繼承