跟老齊學(xué)Python之編寫類之三子類
關(guān)于類,看官想必已經(jīng)有了感覺,看下面的代碼,請仔細閱讀,并看看是否能夠發(fā)現(xiàn)點什么問題呢?
#!/usr/bin/env python
#coding:utf-8
class Person:
def __init__(self, name, lang, email):
self.name = name
self.lang = lang
self.email = email
def author(self):
return self.name
class Programmer:
def __init__(self, name, lang, email, system, website):
self.name = name
self.lang = lang
self.email = email
self.system = system
self.website = website
def pythoner(self):
pythoner_list = [ self.name, self.lang, self.email, self.system, self.website ]
return pythoner_list
if __name__=="__main__":
writer = Person("qiwsir","Chinese","qiwsir@gmail.com")
python = Programmer("qiwsir","Python","qiwsir@gmail.com","Ubutun","qiwsir.github.io")
print "My name is:%s"%writer.author()
print "I write program by:%s"%python.pythoner()[1]
上面這段代碼,運行起來沒有什么問題,但是,仔細看,發(fā)現(xiàn)有兩個類,一個名字叫做Person,另外一個叫做Programmer,這還不是問題所在,問題所在是這兩個類的構(gòu)造函數(shù)中,存在這相同的地方:self.name=name,self.lang=lang,self.email=email,這對于追求代碼質(zhì)量的程序員,一般是不允許的。最好不要有重復(fù)代碼或者冗余代碼。可是,在兩個類中都要有這些參數(shù),應(yīng)該怎么辦呢?
子類、父類和繼承
看下面的代碼,里面有兩個類A,B。這段程序能夠正確運行,每個類的功能是僅僅打印指定的內(nèi)容。
#!/usr/bin/env python
#coding:utf-8
class A:
def __init__(self):
print "aaa"
class B:
def __init__(self):
print "bbb"
if __name__=="__main__":
a = A()
b = B()
#運行結(jié)果
aaa
bbb
上面的兩個類彼此之間沒有所謂的父子關(guān)系。現(xiàn)在稍加改變,將類B改寫,注意觀察與上面的差異。
#coding:utf-8
class A:
def __init__(self):
print "aaa"
class B(A): #這里和上面程序不同。B繼承了A
def __init__(self):
print "bbb"
if __name__=="__main__":
a = A()
b = B()
#運行結(jié)果
aaa
bbb
這段程序中,類B跟前面的那段有一點不同,class B(A):,這樣寫就表明了B相對A的關(guān)系:B是A的子類,B從A繼承A的所有東西(子承父業(yè))。
但是,看官發(fā)現(xiàn)了沒有,運行結(jié)果一樣。是的,那是以為在B中盡管繼承了A,但是沒有調(diào)用任何A的東西,就好比兒子從老爸那里繼承了財富,但是兒子一個子也沒動,外界看到的和沒有繼承一樣。
#!/usr/bin/env python
#coding:utf-8
class A:
def __init__(self):
print "aaa"
class B(A):
def __init__(self):
#print "bbb"
A.__init__(self) #運行繼承的父類
if __name__=="__main__":
a = A()
b = B()
#運行結(jié)果
aaa
aaa
這回運行結(jié)果有了變化,本來b=B()是運行類B,但是B繼承了A,并且在初始化的構(gòu)造函數(shù)中,引入A的構(gòu)造函數(shù),所以,就運行A的結(jié)果相應(yīng)結(jié)果了。
下面把最開頭的那端程序用子類繼承的方式重寫,可以是這樣的:
#!/usr/bin/env python
#coding:utf-8
class Person:
def __init__(self, name, lang, email):
self.name = name
self.lang = lang
self.email = email
def author(self):
return self.name
"""
class Programmer:
def __init__(self, name, lang, email, system, website):
self.name = name
self.lang = lang
self.email = email
self.system = system
self.website = website
def pythoner(self):
pythoner_list = [ self.name, self.lang, self.email, self.system, self.website ]
return pythoner_list
"""
class Programmer(Person): #繼承父類Person
def __init__(self, name, lang, email, system, website):
Person.__init__(self,name,lang,email) #將Person.__init__()的功能繼承到這里
#self.name = name #這三句是Person中已經(jīng)搞定的,就不用重復(fù)
#self.lang = lang #通過繼承已經(jīng)實現(xiàn)了這三句的功能
#self.email = email
self.system = system #子類中不同于Person父類部分
self.website = website
def pythoner(self):
pythoner_list = [ self.name, self.lang, self.email, self.system, self.website ]
return pythoner_list
if __name__=="__main__":
writer = Person("qiwsir","Chinese","qiwsir@gmail.com")
python = Programmer("qiwsir","Python","qiwsir@gmail.com","Ubutun","qiwsir.github.io")
print "My name is:%s"%writer.author()
print "I write program by:%s"%python.pythoner()[1]
代碼運行結(jié)果與前面一樣。
列位是否理解了子類和父類、繼承的特點。如果你有一個老爹,是一個高官或者富豪,那么你就官二代或者富二代了,你就從他們那里繼承了很多財富,所以生活就不用太勞累了。這就是繼承的作用。在代碼中,也類似,繼承能夠讓寫代碼的少勞累一些。
對于為什么要用繼承,好友@令狐蟲 大俠給了以非常精彩的解釋:
從技術(shù)上說,OOP里,繼承最主要的用途是實現(xiàn)多 態(tài)。對于多態(tài)而言,重要的是接口繼承性,屬性和行為是否存在繼承性,這是不一定的。事實上,大量工程實踐表明,重度的行為繼承會導(dǎo)致系統(tǒng)過度復(fù)雜和臃腫, 反而會降低靈活性。因此現(xiàn)在比較提倡的是基于接口的輕度繼承理念。這種模型里因為父類(接口類)完全沒有代碼,因此根本談不上什么代碼復(fù)用了。
在Python里,因為存在Duck Type,接口定義的重要性大大的降低,繼承的作用也進一步的被削弱了。
另外,從邏輯上說,繼承的目的也不是為了復(fù)用代碼,而是為了理順關(guān)系。
我表示完全贊同上述解釋。不過看官如果不理解,也沒有關(guān)系,上述解釋中的精神,的確需要在編程實踐中感悟才能領(lǐng)會到的。
相關(guān)文章
Python使用selenium實現(xiàn)網(wǎng)頁用戶名 密碼 驗證碼自動登錄功能
這篇文章主要介紹了Python使用selenium實現(xiàn)網(wǎng)頁用戶名 密碼 驗證碼自動登錄功能,實現(xiàn)思路很簡單,感興趣的朋友跟隨腳本之家小編一起學(xué)習(xí)吧2018-05-05
python繪制BA無標度網(wǎng)絡(luò)示例代碼
今天小編就為大家分享一篇python繪制BA無標度網(wǎng)絡(luò)示例代碼,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2019-11-11
淺談Python3識別判斷圖片主要顏色并和顏色庫進行對比的方法
這篇文章主要介紹了淺談Python3識別判斷圖片主要顏色并和顏色庫進行對比的方法,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-10-10
Python?NumPy科學(xué)計算庫的高級應(yīng)用
這篇文章主要為大家介紹了Python?NumPy科學(xué)計算庫的高級應(yīng)用深入詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2023-07-07
Python使用xlrd和xlwt實現(xiàn)自動化操作Excel
這篇文章主要介紹了Python使用xlrd和xlwt實現(xiàn)自動化操作Excel,xlwt只能對Excel進行寫操作。xlwt和xlrd不光名字像,連很多函數(shù)和操作格式也是完全相2022-08-08
Python3+django2.0+apache2+ubuntu14部署網(wǎng)站上線的方法
這篇文章主要介紹了Python3+django2.0+apache2+ubuntu14部署網(wǎng)站上線的方法,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2018-07-07

