![2023學年完整公開課版python面向對象_第1頁](http://file4.renrendoc.com/view/ffa9d951bb9cce01050d24053bb96022/ffa9d951bb9cce01050d24053bb960221.gif)
![2023學年完整公開課版python面向對象_第2頁](http://file4.renrendoc.com/view/ffa9d951bb9cce01050d24053bb96022/ffa9d951bb9cce01050d24053bb960222.gif)
![2023學年完整公開課版python面向對象_第3頁](http://file4.renrendoc.com/view/ffa9d951bb9cce01050d24053bb96022/ffa9d951bb9cce01050d24053bb960223.gif)
![2023學年完整公開課版python面向對象_第4頁](http://file4.renrendoc.com/view/ffa9d951bb9cce01050d24053bb96022/ffa9d951bb9cce01050d24053bb960224.gif)
![2023學年完整公開課版python面向對象_第5頁](http://file4.renrendoc.com/view/ffa9d951bb9cce01050d24053bb96022/ffa9d951bb9cce01050d24053bb960225.gif)
版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領
文檔簡介
第6章類Python程序設計基礎教程(慕課版)工業(yè)和信息化人才培養(yǎng)規(guī)劃教材國家精品資源共享課程配套教材高職高專計算機系列人民郵電出版社我們已經(jīng)接觸過多種數(shù)據(jù)類型:數(shù)字、字符串、元組、列表、字典等。它們可以用來描述不同的實際需要,適用不同的場合,解決不同的問題。本章將介紹另一種數(shù)據(jù)類型:類(class)。本章導讀Thechapter’sintroduction目錄導航6.1類和對象6.1.1類與對象的概念6.1.3對象:類的實例化6.2對類的進一步認識6.1.2Python中類的定義6.2.1關于初始化程序:__init__6.2.2關于參數(shù):self6.2.3關于類的屬性6.3類的繼承6.4Python中類的導入6.3.1Python里類的繼承6.3.2在子類中改寫父類的方法6.4.1類的導入6.4.2導入多個類6.3.3內置函數(shù)super()6.3.4多重繼承6.1.1類與對象的概念例如,一說到球,人的頭腦中馬上就會把它想象成一種圓形的物體,它的大小由半徑?jīng)Q定,它的外表可以有不同顏色;對球施以外力后,它會往遠處滾動,或上下來回彈跳。但是,我們能真正拿出一個叫“球”的物體嗎?不可能,世上沒有一個東西具體叫作“球”,只有諸如“乒乓球”“籃球”“排球”等,才是實實在在的“球”。因此,“球”與“乒乓球”等不是一回事。“球”,是對諸如“乒乓球”“籃球”“排球”等的一種抽象;而“乒乓球”“籃球”“排球”等,則是對“球”的一個個具體化?!扒颉笔菆A的,大小由半徑?jīng)Q定,外表可以有不同顏色,施加外力后會滾動或彈跳,這些抽象的特征和行為,都是從“乒乓球”“籃球”“排球”等里面抽取出來的;而每一種具體的球,又都必須具有抽取出來的這些特征和行為。于是,人們把抽象的“球”視為是世間的一種數(shù)據(jù)類型——“類”;把具體的“乒乓球”“籃球”“排球”等,視為這種類的“實例化”,或者說是該類的一個個“對象”。6.1.1類與對象的概念可以舉出很多類和對象的例子。例如,“動物”是類,“獅子”“羚羊”“狗”等是動物類的對象。但從另一個角度講,“狗”是一個類,“獵狗”“寵物狗”“藏獒”等又是狗這類的對象?!皩櫸锕贰庇挚梢栽偌毣梢粋€類,“京巴狗”“約克夏”“哈士奇”等是寵物狗類的對象。人們就是以這種“分門別類”的辦法,一點點深入,一點點細化,逐漸對世間萬物進行了解、描述和研究。從上面的討論可以得出下面的兩點共識。“類”是一種抽象的概念,它代表了現(xiàn)實世界中某些事物的共有特征和行為。“對象”是對類的實例化,每個對象都會自動具有所屬類的通用特征和行為。當然,根據(jù)需要,對象也可以具有自己獨特的個性特征與行為。目錄導航6.1類和對象6.1.1類與對象的概念6.1.3對象:類的實例化6.2對類的進一步認識6.1.2Python中類的定義6.2.1關于初始化程序:__init__6.2.2關于參數(shù):self6.2.3關于類的屬性6.3類的繼承6.4Python中類的導入6.3.1Python里類的繼承6.3.2在子類中改寫父類的方法6.4.1類的導入6.4.2導入多個類6.3.3內置函數(shù)super()6.3.4多重繼承6.1.2Python中類的定義Python中的類是借助關鍵字class來定義的。具體語法如下:它由兩大部分組成,以class開頭、“:”冒號結束的第1行被稱為“類頭”,縮進的<成員變量>與<成員函數(shù)>被稱為“類體”。其中,<類名>必須符合Python對變量取名所做的規(guī)定。進一步地,為了便于區(qū)分,Python約定<類名>的第1個字母必須大寫。<成員變量>就是類的成員屬性,簡稱“屬性”。<成員變量>包含在描述該類成員(也就是對象)共有的抽象特征時涉及的各種變量。class<類名>():
<成員變量> <成員函數(shù)>6.1.2Python中類的定義下面直接舉出3個Python中類的定義的例子,只要了解了前面關于函數(shù)的那些知識,那么大致理解例子中所要描述的內容便不會有太大的難度。<成員函數(shù)>即成員方法,簡稱“方法”。<成員函數(shù)>包含描述該類成員(也就是對象)所具有的抽象行為或動作的各種函數(shù)。在一個“類”的定義里,<成員變量>和<成員函數(shù)>當然可以不止一個。classDog():#定義類Dog def__init__(self,name,age): =name self.age=age defsit(self): print(.title()+'isnowsitting.') defr_over(self): print(.title()+'rolledover!')例6-1定義一個“狗”類:6.1.2Python中類的定義該類的名字是Dog,它的首字母為大寫,符合Python對類的定義所做的約定要求。在縮進的類體里面,包含3個以def開頭的函數(shù)。第1個是名為__init__的特殊方法,它是“初始化程序”。在創(chuàng)建對象時,用來為代表屬性的諸變量賦初值。例如,類Dog里有3個形參,即self、name、age,除了特殊的self后面會專門講述它的作用外,name和age兩個屬性的初值都會由創(chuàng)建對象(即實例化)語句提供的實參傳遞過來。第2個是名為sit(坐)的函數(shù),它是描述狗會“坐”的這種行為的方法。該方法只有一個特殊參數(shù)self,功能是把狗名的第1個字母改為大寫(由調用函數(shù)title()來實現(xiàn)),并輸出“isnowsitting”信息。如果在此能夠插入一些動畫,那么就應該出現(xiàn)一條狗蹲坐在那里、舌頭吐在嘴外面呼呼喘氣的情景。第3個是名為r_over(奔跑)的函數(shù),它是描述狗會“跑”的這種行為的方法。該方法只有一個特殊參數(shù)self,功能是把狗名的第1個字母改為大寫(由調用函數(shù)title()來實現(xiàn)),并輸出“rolledover!”信息。如果這里能夠插入動畫,那么就應該出現(xiàn)一條狗向前奔跑的情景。6.1.2Python中類的定義classEmployee(): #定義類Employeee_count=0
def__init__(self,name,salary): #初始化程序
=nameself.salary=salaryEmployee.e_count+=1
defdis_employee(self): #輸出雇員信息
print('Name:',,',Salary:',self.salary)例6-2定義一個“雇員”類:該類的名字是Employee,它的首字母為大寫,符合Python的約定要求。在縮進的類體里,先是為一個變量e_count賦初值0,由于它在類體的最前面,所以這個變量在整個類的定義里都有效,也就是類里定義的函數(shù)都可以使用它。6.1.2Python中類的定義該類里,第1個是名為__init__的初始化程序,我們后面會對它進行專門的講述。除去特殊參數(shù)self外,它的兩個屬性name、salary的初始值,仍然是在創(chuàng)建對象(即實例化)時,靠創(chuàng)建語句通過實參傳遞過來。在這個方法里,還對變量e_count進行計數(shù)操作。該類體里的第2個函數(shù)是dis_employee(),只有一個特殊參數(shù)self,功能是輸出雇員的名單。importmath #導入標準函數(shù)庫mathclassCircle(): #定義類Circle def__init__(self,radius=14): self.radius=radius defd_diameter(self): #返回直徑的方法
return2*self.radius defc_perimeter(self): #返回圓周長的方法
return2*self.radius*math.pi defr_area(self): #返回圓面積的方法
returnself.radius*self.radius*math.pi例6-3定義一個關于“圓”類:6.1.2Python中類的定義該類的名字是Circle,它的首字母為大寫,符合Python的約定要求。注意,在整個類定義的外面,有一條導入語句“importmath”,表明該類里要用到有關數(shù)學計算的標準函數(shù)庫。縮進的類體里有4個函數(shù):第1個仍然是名為__init__的初始化程序,它除了特殊參數(shù)self外,還有一個名為radius(半徑)的默認參數(shù),取默認值為14。第2個方法名為d_diameter,只有一個特殊參數(shù)self,功能是返回圓的直徑;第3個方法名為c_perimeter,只有一個特殊參數(shù)self,功能是返回圓周長;第4個方法名為r_area,只有一個特殊參數(shù)self,功能是返回圓面積。6.1.2Python中類的定義比較以上給出的3個類的定義,可以得到下面這樣的一些對類的認識:當使用前面那些單一數(shù)據(jù)類型無法描述出世間的事物時,就應該考慮采用“類”這種數(shù)據(jù)類型;類名字的第1個字母,應該遵循大寫的規(guī)則;類定義中,可以有一個名為__init__的初始化程序(它實際上也是一個方法),在它的里面聚集了抽象出來的屬性;類中的各種方法里,即使是初始化程序,都有一個特殊的參數(shù)self,它總是被放在方法形參表的第1個位置處,哪怕方法里沒有任何別的參數(shù),這個self都是不可或缺的。綜上所述,Python的類的定義,是把解決問題時需要用到的變量(即屬性)和函數(shù)(即方法)組合在了定義中。通常,稱這種組合為“封裝”,前面的那些數(shù)據(jù)類型,都不可能實現(xiàn)這種把變量和方法封裝在一起的效果。01OPTION02OPTION03OPTION04OPTION目錄導航6.1類和對象6.1.1類與對象的概念6.1.3對象:類的實例化6.2對類的進一步認識6.1.2Python中類的定義6.2.1關于初始化程序:__init__6.2.2關于參數(shù):self6.2.3關于類的屬性6.3類的繼承6.4Python中類的導入6.3.1Python里類的繼承6.3.2在子類中改寫父類的方法6.4.1類的導入6.4.2導入多個類6.3.3內置函數(shù)super()6.3.4多重繼承6.1.3對象:類的實例化定義了類,就可以進行類的實例化工作了。也就是說,可以從“抽象”轉為“具體”,創(chuàng)建出一個個現(xiàn)實世界中的對象來。創(chuàng)建的對象可以通過“對象名.成員”的方式,訪問類中所列的<成員變量>和<成員函數(shù)>。例6-2中有關雇員的實例化。例如在類Employee定義的基礎上,編寫程序主體如下:emp1=Employee('Zara',2000) #創(chuàng)建一個名為emp1的對象emp2=Employee('Manni',5000) #創(chuàng)建一個名為emp2的對象emp1.dis_employee() #emp1調用方法dis_employee()emp2.dis_employee() #emp2調用方法dis_employee()print('TotalEmployee%d'%Employee.e_count) #輸出雇員數(shù)6.1.3對象:類的實例化該程序有3部分內容。先是通過類Employee創(chuàng)建兩個對象,即emp1和emp2,創(chuàng)建過程與調用函數(shù)類似,把實參“'Zara',2000”和“'Manni',5000”分別傳遞給類里的形參name和salary。注意,前面一再提及的特殊參數(shù)self沒有出現(xiàn),沒有傳遞。其次是創(chuàng)建完對象后,采用句號分隔的辦法,用不同的對象名,兩次調用類中的方法dis_employee(),目的是利用該方法輸出該雇員的信息。注意,類中方法里的self參數(shù)仍然沒有出現(xiàn)。第3個內容是一條print語句,輸出雇員數(shù)e_count。把類定義及程序主體合并在一起,然后保存并投入運行,結果如圖6-1所示。這就是一個簡單的面向對象的程序設計過程:先定義一個類,把有關的屬性和方法封裝在一起;然后創(chuàng)建對象,完成實例化;最后是程序的執(zhí)行,獲得所需要的結果。圖6-16.1.3對象:類的實例化classEmployee():e_count=0def__init__(self,name,salary):=nameself.salary=salaryEmployee.e_count+=1defdis_employee(self):print('Name:',,',Salary:',self.salary)emp1=Employee('Zara',2000) #創(chuàng)建一個名為emp1的對象emp2=Employee('Manni',5000) #創(chuàng)建一個名為emp2的對象emp1.dis_employee() #emp1調用方法dis_employee()emp2.dis_employee() #emp2調用方法dis_employee()print('TotalEmployee%d'%Employee.e_count) #輸出雇員數(shù)程序編寫如下:6.1.3對象:類的實例化firstA=Circle(17) #創(chuàng)建一個名為firstA的對象firstB=Circle() #創(chuàng)建一個名為firstB的對象print('InformationonfirstA:')print('Radiusofthegarden',firstA.radius)print('Diameterofthegarden:',firstA.d_diameter())print('Gardenarea:',firstA.r_area())print('Gardenperimeter:',firstA.c_perimeter())print('\nInformationonfirstB:')print('Radiusofthegarden',firstB.radius)print('Diameterofthegarden:',firstB.d_diameter())print('Gardenarea:',firstB.r_area())print('Gardenperimeter:',firstB.c_perimeter())再來看例6-3里定義的“圓”類,編寫程序主體如下:6.1.3對象:類的實例化程序開始處,通過類Circle創(chuàng)建了兩個對象,一個名為firstA,一個名為firsrB。在類Circle的初始化程序里,除了特殊參數(shù)self外,有一個默認參數(shù)radius,創(chuàng)建firstA對象時,沒有使用這個默認參數(shù),而是把自己的參數(shù)值17傳遞了過去;創(chuàng)建firstB對象時,使用了默認參數(shù),所以無須傳遞任何參數(shù)給類的初始化程序。這些用法完全與函數(shù)相同。緊接著是分兩組輸出語句輸出兩個實例化的圓的半徑、圓的直徑、圓的面積、圓的周長。把類定義及程序主體合并在一起,然后保存并執(zhí)行,結果如圖6-2所示。圖6-26.1.3對象:類的實例化importmathclassCircle(): def__init__(self,radius=14): self.radius=radius defd_diameter(self): return2*self.radius defc_perimeter(self): return2*self.radius*math.pi defr_area(self): returnself.radius*self.radius*math.pi程序編寫如下:firstA=Circle(17)firstB=Circle()print('InformationonfirstA:')print('Radiusofthegarden',firstA.radius)print('Diameterofthegarden:',firstA.d_diameter())print('Gardenarea:',firstA.r_area())print('Gardenperimeter:',firstA.c_perimeter())print('\nInformationonfirstB:')print('Radiusofthegarden',firstB.radius)print('Diameterofthegarden:',firstB.d_diameter())print('Gardenarea:',firstB.r_area())print('Gardenperimeter:',firstB.c_perimeter())目錄導航6.1類和對象6.1.1類與對象的概念6.1.3對象:類的實例化6.2對類的進一步認識6.1.2Python中類的定義6.2.1關于初始化程序:__init__6.2.2關于參數(shù):self6.2.3關于類的屬性6.3類的繼承6.4Python中類的導入6.3.1Python里類的繼承6.3.2在子類中改寫父類的方法6.4.1類的導入6.4.2導入多個類6.3.3內置函數(shù)super()6.3.4多重繼承6.2.1關于初始化程序:__init__下面羅列幾個編寫初始化程序時需要了解的問題。#下面是定義的函數(shù),它有了返回值defodd_even(x): if(x%2==0): result=True else: result=False returnresult #return必須保證在函數(shù)體的縮進范圍內#下面是調用函數(shù)的程序print('Pleaseenteraninteger!')num=input('Enteraninteger:')y=int(num)#調用函數(shù)odd_even(),變量z接收函數(shù)的返回值z=odd_even(y) ifz==True: print('It\'sanevennumber!')else: print('It\'sanoddnumber!')print('End')6.2.1關于初始化程序:__init__下面羅列幾個編寫初始化程序時需要了解的問題。1.初始化程序的正確寫法:兩條下劃線初始化程序的名字,是以兩條下劃線開始,以兩條下劃線結束的。如果哪一邊只有一條下劃線,那么就會輸出圖6-3所示的出錯信息,表明創(chuàng)建對象時,實參無法傳遞給類,導致對象得不到參數(shù)。這種錯誤提示得非常隱晦,讓人難以發(fā)現(xiàn)到底是在哪里出了問題,其實只是因為丟失了一條小小的下劃線“—”。2.初始化程序,不一定非要排在類定義的最前面初始化程序的名字是固定的,只能寫成“__init__”。因此,只要保證它出現(xiàn)在類定義語句塊的里面就行,至于是塊中的第1個方法(如例6.1~6.3那樣),還是第幾個方法,完全無關緊要;甚至如果不需要傳遞什么參數(shù),在類的定義中不編寫初始化程序也沒有什么關系。Python在創(chuàng)建一個新的對象(即實例化)時,總是用這個名字去匹配類中所包含的方法名,找到這個名字,就執(zhí)行并僅執(zhí)行它一次,以完成初始化的工作;如果沒有找到它,那就不做初始化工作。6.2.1關于初始化程序:__init__3.初始化程序中name與的不同含義例如在例6-2的類定義中,初始化程序如下:def__init__(self,name,salary):=nameself.salary=salaryEmployee.e_count+=1在它的里面除self外,還有兩個位置參數(shù):name、salary。一進入初始化程序,就執(zhí)行:=nameself.salary=salary把接收到的實參(在name和salary里),賦予變量和self.salary。因此,這兩條語句右邊的name和salary,是初始化程序接收到的傳遞過來的實參,而左邊的與self.salary是兩個變量,由它們接收并存放這個新建對象的具體屬性值。6.2.1關于初始化程序:__init__既然左邊的與self.salary是兩個變量名稱,因此除了前面的self不能變以外,句號分隔的name與salary完全可以另取名字,例如改名為self.ad和self.bc,這也是完全可以接受的。人們之所以喜歡將它們取名為與self.salary,主要是因為name、salary是類的屬性名,有它們就知道這個變量里面存放的是什么屬性值。例如,把前面給出的類Dog里面的:=nameself.age=age改為:self.ad=nameself.bc=age6.2.1關于初始化程序:__init__classDog(): def__init__(self,name,age): self.ad=name #變量名變了
self.bc=age #變量名變了
defsit(self): print(self.ad.title()+'isnowsitting.') #這里要做相應改動
defr_over(self): print(self.ad.title()+'rolledover!') #這里要做相應改動mdog=Dog('willams',6)print('Mydog\'snameis'+str(mdog.ad.title())+'.') #這里要做相應改動print('Mydogis'+str(mdog.bc)+'yearold!') #這里要做相應改動整個類和程序如下所示:運行該程序,完全可以得到正確的結果。不過要注意的是,如果把類中接收實參值的變量名改了,那么程序中相應的地方也都要改動,否則就會出錯。目錄導航6.1類和對象6.1.1類與對象的概念6.1.3對象:類的實例化6.2對類的進一步認識6.1.2Python中類的定義6.2.1關于初始化程序:__init__6.2.2關于參數(shù):self6.2.3關于類的屬性6.3類的繼承6.4Python中類的導入6.3.1Python里類的繼承6.3.2在子類中改寫父類的方法6.4.1類的導入6.4.2導入多個類6.3.3內置函數(shù)super()6.3.4多重繼承6.2.2關于參數(shù):self例6-4下面是一個用類編寫的極為簡單的圖書查詢的例子(為方便講述,各部分程序分散列在下面):#定義一個字典catalogcatalog={'aa':3,'bb':0,'cc':5,'dd':2,'ee':4,'ff':1,'gg':8,'hh':3}#定義類BookclassBook(): globalcatalog def__init__(self,name): =name #下面是類中的方法loop(),供創(chuàng)建的對象調用
defloop(self,name): forkey,valueincatalog.items(): ifkey==name: ifvalue!=0: print('Thereisthebook!') elifvalue==0: print('I\'msorrythatthebookhasbeenborrowed!') else: print('It\'sapitythatthereisnobook!') break6.2.2關于參數(shù):self#下面是類中的方法seek(),供創(chuàng)建的對象調用defseek(self,pword,name,value): ifpword!='12345': returnprint('Youdon\'thavetherighttoaddanewbook!') else: catalog[name]=value print(catalog)整個程序開始,先定義一個字典catalog,書名aa、bb、cc等是字典的鍵;現(xiàn)存書的數(shù)量是字典的值。由于字典catalog是在整個程序外定義的,進入類后才使用它,這樣可能會引起不必要的誤解,所以在類的里面用語句globalcatalog表明類里出現(xiàn)的catalog就是外面定義的全局變量catalog。整個類Book里有3個函數(shù)。6.2.2關于參數(shù):self第1個是初始化程序__init__,它有兩個參數(shù),一個是self,一個是name。實例化時,name將接收傳遞過來的書名,并將其賦予變量。第2個方法名為loop,它有兩個參數(shù),一個是self,一個是是希望查找的書名,通過對字典catalog的遍歷,給出查找的結果。在查找過程中,考慮這樣幾個問題:找到,且當前有這本書(數(shù)量不為0);找到,但當前沒有這本書可外借(數(shù)量為0);沒有找到這本書,查找失敗。不同的情況會輸出不同的信息:找到且當前有此書,輸出信息“Thereisthebook!”;找到但當前沒有這本書,輸出信息“I'msorrythatthebookhasbeenborrowed!”;沒有找到所需要的書,則輸出信息“It'sapitythatthereisnobook!”。第3個方法名為seek,它有4個參數(shù),self、pword、name、value。后面3個參數(shù),一個是口令(pword)、一個是要添加的書名(name)、一個是數(shù)量(value)。只有在調用方法loop()查找沒有結果時,才有可能往字典里添加新書;只有在輸入的口令正確時,才能往字典里添加新書。也就是說,不是隨便什么人都可以往字典里添加新書的。6.2.2關于參數(shù):self程序主體分為兩段:一個是創(chuàng)建類Book的對象studentA,在輸入書名后,調用類的方法loop(),以便查找是否有所需的書目;另一個是創(chuàng)建類Book的對象studentB,在輸入書名后,調用類的方法loop(),只有在調用方法loop()無結果的情況下,才去輸入口令、數(shù)量,才去調用方法seek(),才有可能把新書添加到字典中去。程序編寫如下:#下面是程序中創(chuàng)建的對象studentAbk=input('Enterthetitleoftherequiredbook:')studentA=Book(bk)studentA.loop(bk)#下面是程序中創(chuàng)建的對象studentBbnm=input('Enterbookname:')studentB=Book(bnm)studentB.loop(bnm)psw=input('Enterpassword:')num=input('Enternubmer:')studentB.seek(psw,bnm,num)目錄導航6.1類和對象6.1.1類與對象的概念6.1.3對象:類的實例化6.2對類的進一步認識6.1.2Python中類的定義6.2.1關于初始化程序:__init__6.2.2關于參數(shù):self6.2.3關于類的屬性6.3類的繼承6.4Python中類的導入6.3.1Python里類的繼承6.3.2在子類中改寫父類的方法6.4.1類的導入6.4.2導入多個類6.3.3內置函數(shù)super()6.3.4多重繼承6.2.3關于類的屬性1.給類的屬性指定默認值借助上面的例6-4,在類Book的定義里,給出一個取默認值的屬性“self.word='12345'”,并利用它作為口令的初始值。圖6-4所示是兩次運行的情形,一次是口令輸入正確,將希望添加的書目(書名:xx,數(shù)量:3)添加到字典里;一次是口令輸入錯誤,無法將書目添加到字典里去。這時的程序(缺少創(chuàng)建對象部分)如下:catalog={'aa':3,'bb':0,'cc':5,'dd':2,'ee':4,'ff':1,'gg':8,'hh':3}classBook(): globalcatalog def__init__(self,name): =name self.word='12345' #設置屬性word默認的初始值,它不出現(xiàn)在參數(shù)表里6.2.3關于類的屬性defloop(self,name): forkey,valueincatalog.items(): ifkey==name: ifvalue!=0: print('Thereisthebook') elifvalue==0: print('I\'msorrythatthebookhasbeenborrowed!') else: print('It\'apitythatthereisnobook!') breakdefseek(self,pword,name,value): ifpword!=self.word: #用到屬性word默認的初始值 returnprint('Youdon\'thavetherighttoaddanewbook!') else: catalog[name]=value print(catalog)6.2.3關于類的屬性bnm=input('Enterbookname:')studentB=Book(bnm)studentB.loop(bnm)psw=input('Enterpassword:')num=input('Enternubmer:')studentB.seek(psw,bnm,num)圖6-42.對類的默認屬性值的修改每種類都有自己的屬性和方法,屬性是從類的實例化中抽象出來的特征,由變量來描述;方法是從類的實例化中抽象出來的行為,由函數(shù)來描述。因此,修改類的屬性值,就是修改描述它的變量的值,這是非常容易做到的事情。6.2.3關于類的屬性修改默認屬性值最直接的辦法,是在創(chuàng)建的實例里進行。例如上面原先設置的默認屬性值是:self.word='12345'只要在實例化studentB的程序里,增加一條語句:studentB.word='67890'于是,現(xiàn)在創(chuàng)建對象studentB時的程序就改寫為:bnm=input('Enterbookname:')studentB=Book(bnm)studentB.loop(bnm)studentB.word='67890' #對默認屬性值的修改psw=input('Enterpassword:')num=input('Enternubmer:')studentB.seek(psw,bnm,num)這時再運行程序,只有輸入的口令是“67890”,才會允許將輸入的書目和數(shù)量添加到字典catalog里;否則是通不過口令的檢查的。6.2.3關于類的屬性3.屬性的增、刪、改定義一個類并創(chuàng)建了它的對象后,可以對定義的類進行添加新屬性、修改原有屬性、刪除已有屬性的操作。下面的程序中,定義了一個名為Car的類,它有一個形參col,有兩個默認參數(shù):price=100000和name=“QQ”。#定義的類Car:classCar: def__init__(self,col): self.color=col self.price=100000 ='QQ'#程序主體:car1=Car('Red')print(,car1.color,car1.price)car1.price=110000car1.color='Yellow'car1.time='2016/08'print(,car1.color,car1.price,car1.time)delcar1.colorprint(,car1.color,car1.price,car1.time)print('End')6.2.3關于類的屬性程序主體里,創(chuàng)建了一個名為car1的對象,隨之通過語句:print(,car1.color,car1.price)輸出信息“QQRed100000”。接著有語句:car1.price=110000car1.color='Yellow'car1.time='2016/08'前兩條是修改已有屬性price和color,后一條語句是增加新屬性time(出廠時間)。這樣的操作,使得程序主體中的第2條輸出語句輸出了這輛QQ的新信息。最后,通過語句:delcar1.color刪除對象car1的屬性color。第3條輸出語句的執(zhí)行,就會產(chǎn)生出錯信息:AttributeError:'Car'objecthasnoattribute'color'6.2.3關于類的屬性表示試圖刪除對象沒有的屬性,操作失敗。圖6-5記錄了程序的整個執(zhí)行過程。圖6-54.屬性的保護如上所述,在程序主體中可以對對象的屬性進行增、刪、改等操作。這種做法看似很方便,用起來也得心應手,但卻違反了類的封裝原則:數(shù)據(jù)使用的安全性。對象能夠在類定義的外部隨便訪問其數(shù)據(jù)屬性,就有可能修改它們,影響到類中提供的各種方法的正確運行,因為在類定義里給出的方法里面可能會用到屬性變量。6.2.3關于類的屬性類定義中的屬性變量沒有了私密性,就可能會帶來各種想象不到的麻煩。考慮到這些問題,Python對類的屬性提供了一種自我保護的簡單辦法。具體做法如下。classCar: def__init__(self,col): self.__color=col self.price=100000 ='QQ' defpri(self): print(self.__color)01OPTION02OPTION在需要具有私密性的屬性變量名前,加上雙下劃線。在類定義里增加供程序設計人員訪問屬性變量的接口。仍以上面所定義的類Car來加以說明。car1=Car('Red')print(,car1.price)car1.pri()print('End')6.2.3關于類的屬性假定要保護屬性col的使用,不允許在程序主體內隨意地訪問它,那么可以在類定義中,在接收col的形參名前增加雙下劃線,即:self.__color另一方面,在類定義中寫一個輸出汽車顏色的方法:defpri(self): print(self.__color)以便在程序主體內能夠輸出汽車的顏色。classCar: def__init__(self,col): self.__color=col self.price=100000 ='QQ'先看一下在形參名前加上雙下劃線后的作用。這時整個程序是這樣的:car1=Car('Red')print(,car1.price,car1.color)print('End')6.2.3關于類的屬性運行該程序,結果如圖6-6所示,給出出錯信息:AttributeError:'Car'objecthasnoattribute'color'之所以會這樣,是因為類定義里,在屬性color變量名前加上了雙下劃線,Python對該變量進行了保護,不允許在類外通過“car1.color”直接訪問該屬性。為了能夠在類定義外訪問屬性color,可以在類定義里給出訪問該變量的函數(shù),例如pri(),然后在程序主體里,把語句“print(,car1.price,car1.color)”改寫成語句“print(,car1.price)”,增加語句“car1.pri()”。這樣再運行,程序就正確了,如圖6-7所示。圖6-6圖6-76.2.3關于類的屬性classCar: def__init__(self,col): self.__color=col self.price=100000 ='QQ' defpri(self):
#增加的新函數(shù)
print(self.__color)car1=Car('Red')print(,car1.price) #去除直接訪問屬性color的內容car1.pri()
#增加調用類函數(shù)pri()的語句print('End')程序編寫如下:目錄導航6.1類和對象6.1.1類與對象的概念6.1.3對象:類的實例化6.2對類的進一步認識6.1.2Python中類的定義6.2.1關于初始化程序:__init__6.2.2關于參數(shù):self6.2.3關于類的屬性6.3類的繼承6.4Python中類的導入6.3.1Python里類的繼承6.3.2在子類中改寫父類的方法6.4.1類的導入6.4.2導入多個類6.3.3內置函數(shù)super()6.3.4多重繼承6.3.1Python里類的繼承只要遵守Python里“繼承”的規(guī)則,在程序設計中完成繼承是不困難的。例如,簡單定義了一個名為People的類,代碼如下:“繼承”,即承上啟下。一個類,就是把它所要描述事物的特征(即屬性)和行為(即方法)包裝(也就是封裝)在了一起。在繼承關系中,已有的、設計好的類被稱為“父類”或“基類”,新設計的類被稱為“子類”或“派生類”。classPeople(): def__init__(self,name,nationality): =name self.nationality=nationality deftalk(self): print('Communicateinlanguage') defwalk(self): print('Walkuprightwithyourlegs!')6.3.1Python里類的繼承由它派生出來的類,都應該有這樣的屬性和方法,也就是說都會繼承這些屬性和方法。下面定義一個名為Ch_people(中國人)的類:該類名為People,它有3個屬性:self、name、nationality(國籍)。類中定義了兩個方法,一是talk,調用它時輸出信息“Communicateinlanguage”(用語言交流);二是walk,調用它時輸出信息“Walkuprightwithyourlegs”(兩腿直立行走)。classCh_people(People): #定義一個子類,名為Ch_people pass #表示該類不做什么事情在該類名字后面的括號里,填寫了一個參數(shù)“People”,表明它是從類People派生出來的,要繼承它的“衣缽”,也就是繼承它的所有屬性和方法。該類的類體里只有一條語句“pass”,表示雖然定義了這個新類,但它什么事情也不做,它沒有自己新的屬性,也沒有自己新的方法,純粹就是一個“空”的類。6.3.1Python里類的繼承定義了類People和類Ch_people后,編寫如下程序:#創(chuàng)建類People的一個對象peopApeopA=People('Zongdahua','china') print(peopA.name,peopA.nationality)peopA.talk()peopA.walk()#創(chuàng)建類Ch_people的另一個對象peopBpeopB=Ch_people('Zongdahua','china') print(peopB.name,peopB.nationality)peopB.talk()peopB.walk()執(zhí)行整個程序,結果如圖6-8所示。圖6-86.3.1Python里類的繼承上半部分是類People的對象peopA調用方法的結果;下半部分是類Ch_people的對象peopB調用方法的結果。由于類Ch_people是由類People派生出來的,它繼承了類People的一切,自己又不多做任何事情,所以這兩個對象的運行結果是完全一樣的。為了便于描述,常會使用如下的名稱。基類:也稱“父類”,表示這種類是可以被別的類繼承的。派生類:也稱“子類”,表示這種類是一個繼承別的類的類。例如,上面定義的類People,相對于類Ch_people來說,就是一個基類,即父類;而定義的類Ch_people,則是一個從類People派生出來的類,因此是一個子類??偨Y,在Python里,要從一個類里派生出另一個類,也就是一個類要繼承另外一個類,只需將父類的名字放入該類定義的括號里即可。由于在子類的定義里只有一條pass語句,所以它將會從它的父類那里繼承所有的特征和行為。目錄導航6.1類和對象6.1.1類與對象的概念6.1.3對象:類的實例化6.2對類的進一步認識6.1.2Python中類的定義6.2.1關于初始化程序:__init__6.2.2關于參數(shù):self6.2.3關于類的屬性6.3類的繼承6.4Python中類的導入6.3.1Python里類的繼承6.3.2在子類中改寫父類的方法6.4.1類的導入6.4.2導入多個類6.3.3內置函數(shù)super()6.3.4多重繼承6.3.2在子類中改寫父類的方法在繼承機制下,允許子類改寫父類中已經(jīng)出現(xiàn)過的方法。通常,這種改寫被稱為“覆蓋”。deftalk(self): print('Communicateinlanguage')加以改寫(也就是“覆蓋”),例如改寫為:deftalk(self): print('ExchangeideasinChinese!')classCh_people(People): deftalk(self): print('ExchangeideasinChinese!')仍以類Ch_people這個由類People派生出來的類為例。類Ch_people當然是用語言來交流思想的,但類Ch_people是用特定的、自己民族的語言來交流思想的。因此,在定義類Ch_people時,可以將原先類People中的方法:這樣,類Ch_people的定義就可以是:6.3.2在子類中改寫父類的方法即先取消類Ch_people定義中的pass語句,然后再改寫方法talk()?,F(xiàn)在,整個程序變?yōu)椋篶lassPeople(): def__init__(self,name,nationality): =name self.nationality=nationality deftalk(self): print('Communicateinlanguage') defwalk(self): print('Walkontwolegs')classCh_people(People): deftalk(self): #改寫父類中的同名方法talk() print('ExchangeideasinChinese!')peopA=People('Zongdahua','china')print(peopA.name,peopA.nationality)peopA.talk()peopA.walk()peopB=Ch_people('Zongdahua','china')print(peopB.name,peopB.nationality)peopB.talk()peopB.walk()6.3.2在子類中改寫父類的方法運行該程序,結果就與圖6-8有所不同了,如圖6-9所示。圖6-9這時在子類中,利用改寫的初始化程序,就可以使子類增添自己特有的屬性。例如,原先類People只有name和nationality兩個屬性,考慮到中國是一個多民族國家,希望在類Ch_people里,增加一個名為nation的屬性。為此,可以在類Ch_people里,改寫類People里的初始化程序,代碼如下:classCh_people(People):def__init__(self,name,nationality,nation):=nameself.nationality=nationalityself.nation=nation6.3.2在子類中改寫父類的方法當創(chuàng)建類Ch_people的對象時,Python就去執(zhí)行該類如上的初始化程序,從創(chuàng)建處傳遞所需的實參給變量、self.nationality、self.nation,完成初始化工作,以保證整個程序正常運行。下面是整個程序的內容:classPeople(): def__init__(self,name,nationality): =name self.nationality=nationality deftalk(self): print('Communicateinlanguage') defwalk(self): print('Walkontwolegs')classCh_people(People):def__init__(self,name,nationality,nation):=nameself.nationality=nationalityself.nation=nationdeftalk(self):print('Exchangeideaswithnationallanguage!')peopA=People('Zongdahua','china')print(peopA.name,peopA.nationality)peopA.talk()peopA.walk()peopB=Ch_people('Zongdahua','china','Chinese')print(peopB.name,peopB.nationality,peopB.nation)peopB.talk()peopB.walk()6.3.2在子類中改寫父類的方法運行該程序,結果就與圖6-9又不一樣了,如圖6-10所示。圖6-10目錄導航6.1類和對象6.1.1類與對象的概念6.1.3對象:類的實例化6.2對類的進一步認識6.1.2Python中類的定義6.2.1關于初始化程序:__init__6.2.2關于參數(shù):self6.2.3關于類的屬性6.3類的繼承6.4Python中類的導入6.3.1Python里類的繼承6.3.2在子類中改寫父類的方法6.4.1類的導入6.4.2導入多個類6.3.3內置函數(shù)super()6.3.4多重繼承6.3.3內置函數(shù)super()實際應用中,肯定會有這樣的情形發(fā)生:子類改寫了父類的某個方法,后面卻還要用到已被改寫的原先父類的那個方法。Python的內置函數(shù)super()就可以解決這個問題,它建立起了子類與父類之間的聯(lián)系,準確無誤地在子類里找到父類,并實現(xiàn)對所需方法的調用。也就是說,如果需要在子類中調用父類的方法,那么可以使用內置函數(shù)super(),或者通過“父類名.方法名()”的方式,來達到這一目的。classParent(): defspeak(self): print('Thevoiceofthefather\'svoice!')classChild(Parent): passdad=Parent()son=Child()dad.speak()son.speak()例6-5一個全部繼承的例子:6.3.3內置函數(shù)super()例中先定義了一個名為Parent的類,它有一個方法speak(),功能是輸出信息“Thevoiceofthefather'svoice!”(父親的說話聲音)。接著定義一個名為Child的類,它無條件地繼承了類Parent,因為它定義的括號里,有一個參數(shù)“Parent”,且類體里只有一條pass語句。程序里共有4條語句:第1條是dad=Parent(),它創(chuàng)建了一個名為dad的Parent對象;第2條語句是son=Child(),它創(chuàng)建了一個名為son的Child對象;第3條語句是對象dad調用方法speak();第4條語句是對象son調用方法speak()。由于子類Child全盤地繼承了父類,所以這兩個對象調用方法speak()的結果,都是輸出信息“Thevoiceofthefather'svoice!”。6.3.3內置函數(shù)super()如圖6-11最上面所示。圖6-116.3.3內置函數(shù)super()classParent(): defspeak(self): print('Thevoiceofthefather\'svoice!')classChild(Parent): defspeak(self): print('Thevoiceoftheson\'svoice!')dad=Parent()son=Child()dad.speak()son.speak()把例6-5稍加修改,代碼如下:例6-6一個覆蓋父類方法的例子。6.3.3內置函數(shù)super()其他地方都沒有動,只是子類雖然仍繼承父類,但并沒有全盤繼承,而是修改了父類的方法speak(),即如果子類的對象再調用方法speak(),不是輸出信息“Thevoiceofthefather'svoice!”,而是輸出信息“Thevoiceoftheson'svoice!”。程序的運行結果如圖6-11中間所示:父類的方法speak()被子類改寫的方法speak()覆蓋了。圖6-116.3.3內置函數(shù)super()classParent(): defspeak(self): print('Thevoiceofthefather\'svoice!')classChild(Parent): defspeak(self): print('Thevoiceoftheson\'svoice!') super(Child,self).speak()dad=Parent()son=Child()dad.speak()son.speak()把例6-6稍加修改,代碼如下:例6-7利用內置函數(shù)super()的例子6.3.3內置函數(shù)super()其他地方都沒有動,只是子類雖然仍繼承了父類,并改寫了父類的方法speak(),但它的改寫又與例6-6不同,即增加了一條內置函數(shù)super()調用方法speak()的語句“super(Child,self).speak()”。通常,內置函數(shù)super()有兩個參數(shù),第2個是self,表示自己;第1個則是一個類名,表示內置函數(shù)要調用的方法是這個類的父類的那個方法。例如在上述程序中,內置函數(shù)的第1個參數(shù)是Child,因此表明它要調用的那個方法speak(),是父類Child里的那個方法speak(),而不是自己覆蓋的那個方法speak()。按照這樣對內置函數(shù)super()的理解,我們來看程序中最后兩條語句的執(zhí)行結果。dad是類Parent的實例化,son是類Child的實例化。于是,執(zhí)行語句dad.speak(),就是輸出信息:Thevoiceofthefather'svoice!6.3.3內置函數(shù)super()執(zhí)行語句son.speak(),就是要執(zhí)行:print('Thevoiceoftheson\'svoice!')super(Child,self).speak()第1句好理解,即輸出信息:Thevoiceoftheson'svoice!第2句的意思是要去調用類Child的父類的方法speak()。于是就去執(zhí)行類Parent的方法speak(),即輸出信息:Thevoiceofthefather'svoice!于是,該例的執(zhí)行結果如圖6-11最后面所示,即輸出結果:Thevoiceofthefather'svoice!Thevoiceoftheson'svoice!Thevoiceofthefather'svoice!6.3.3內置函數(shù)super()在Python中繼承有以下幾個特點。01OPTION02OPTION03OPTION在繼承中,父類的初始化程序__init__不會被自動調用,Python會先在其派生類的初始化程序中去尋找并調用,只有當子類中沒有初始化程序時,才以父類的初始化程序作為自己的初始化程序。在子類對象里調用父類的方法時,需要以父類的類名作為前綴,并用“.”分隔,還需要帶上self參數(shù)變量。但在一般的類中調用方法時,并不需要帶上self參數(shù)。Python總是首先查找對應類的方法,如果它不能在派生類中找到對應的方法,它才開始到父類中去逐個查找。即先在子類中查找調用的方法,找不到才去父類中查找。6.3.3內置函數(shù)super()classParent(): def__init__(self): #父類的初始化程序
self.parent='I\'mtheparent.' print('Parent') deffun(self,message): #父類的方法fun() print('%sfromparent'%message)classChild(Parent): #子類的初始化程序
def__init__(self): super(Child,self).__init__() print('Child') deffun(self,message): #子類的方法fun() super(Child,self).fun(message) print('Childfunfuction') print(self.parent)#程序主體f_Child=Child()f_Child.fun('HelloPython!')下面是編寫的整個程序,其運行結果如圖6-12所示:例6-8閱讀并對照運行結果,更進一步地理解內置函數(shù)super()。6.3.3內置函數(shù)super()整個程序分為3個部分:第1部分定義了名為Parent的類,它有一個初始化程序、一個名為fun的方法。第2部分定義了一個名為Child的類,類Parent是它的父類,它有自己的初始化程序,也有一個名為fun的方法,也就是說,這個方法覆蓋了它父類中同名的方法。第3部分是程序主體,它僅由兩條語句組成:第1條語句是對類Child的實例化,對象變量是f_Child;第2條語句是該對象以“HelloPython!”為參數(shù),調用方法fun()。執(zhí)行這樣的兩條簡單語句,得到的輸出信息居然會如圖6-12所示。為什么會是這樣呢?f_Child=Child()f_Child.fun('HelloPython!')6.3.3內置函數(shù)super()分析執(zhí)行語句“f_Child=Child()”的情形。這是創(chuàng)建類Child的一個對象,對象的名字是f_Child。類Child繼承了類Parent,且有自己的初始化程序(也就是它改寫了父類的初始化程序),因此創(chuàng)建類Child的對象時,不會去執(zhí)行父類的初始化程序,而是去執(zhí)行自己的初始化程序:def__init__(self): super(Child,self).__init__() print('Child')(1)子類初始化程序的第1條語句:super(Child,self).__init__()。其含義是通過內置函數(shù)super()調用名為__init__()的初始化程序。父類有初始化程序,子類也有初始化程序,這里是調用哪一個初始化程序呢?這將由內置函數(shù)super()里給出的第1個參數(shù)“Child”來指明,即調用類Child的父類的初始化程序。于是,Python轉而去執(zhí)行父類Parent的初始化程序:6.3.3內置函數(shù)super()def__init__(self): self.parent='I\'mtheparent.' print('Parent')(2)子類初始化程序的第2條語句:print('Child')。父類的初始化程序的第1條語句是為變量self.parent賦初值“I’mtheparent”。第2條語句輸出信息“Parent”。于是,在圖6-12中輸出的第1條信息是“Parent”。含義是輸出信息“Child”。于是,在圖6-12里接著輸出了“Child”。至此,語句f_Child=Child()就分析并執(zhí)行完了。分析執(zhí)行語句“f_Child.fun('HelloPython!')”的情形。該語句的意思是由對象f_Child調用(自己的)方法fun(),傳遞的參數(shù)是“HelloPython!”。對象f_Child的方法fun()是:6.3.3內置函數(shù)super()deffun(self,message): super(Child,self).fun(message) print('Childfunfuction') print(self.parent)共有3條語句,現(xiàn)在分析如下。01OPTION子類fun()方法的第1條語句:super(Child,self).fun(message)。該語句是一條內置函數(shù)super(),它要通過傳遞參數(shù)message去調用名為fun的方法。同樣地,父類有名為fun的方法,子類也有名為fun的方法。到底應該調用哪一個將由內置函數(shù)super()括號內的第1個參數(shù)來定。很清楚,是要調用父類Parent的方法fun()。于是,轉而去看父類Parent的方法fun():deffun(self,message): print('%sfromparent'%message)6.3.3內置函數(shù)super()02OPTION子類方法fun()的第2條語句:print('Childfunfuction')。這條語句功能簡單,就是輸出信息:Childfunfuction它的功能就是把message傳遞的信息輸出來?,F(xiàn)在message攜帶的信息是“HelloPython!”,因此在窗口里緊接著會輸出信息:HelloPython!Fromparent(見圖6-12輸出的第
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經(jīng)權益所有人同意不得將文件中的內容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
- 6. 下載文件中如有侵權或不適當內容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025年金剛石膜-聲表面波器件(SAW)項目規(guī)劃申請報告模板
- 2025年絕緣材料:絕緣套管項目提案報告模范
- 2025年個體經(jīng)營物流配送協(xié)議
- 2025年耐高溫可加工陶瓷項目立項申請報告
- 2025年發(fā)泡消泡劑項目規(guī)劃申請報告
- 2025年授權代理業(yè)務綜合合同范本
- 2025年建筑器材租賃合同標桿
- 2025年倉儲物流服務合作協(xié)議合同
- 2025年工業(yè)外包合同中的環(huán)境管理措施
- 2025年城市綠化養(yǎng)護服務合同文本
- 公司財務制度及流程
- 高支模專項施工方案(專家論證)
- 《物流與供應鏈管理-新商業(yè)、新鏈接、新物流》配套教學課件
- 房地產(chǎn)標準踩盤表格模板
- 物聯(lián)網(wǎng)項目實施進度計劃表
- 學校校園安全巡邏情況登記表
- 光纜線路工程段終版施工圖
- 畢業(yè)論文-基于Java Web的模擬駕??荚囅到y(tǒng)設計與實現(xiàn)
- MDD指令附錄一 基本要求檢查表2013版
- 新部編人教版四年級下冊道德與法治全冊教案(教學設計)
- 人美版高中美術選修:《繪畫》全冊課件【優(yōu)質課件】
評論
0/150
提交評論