日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程语言 > python >内容正文

python

python Day6 面向对象学习

發(fā)布時(shí)間:2025/4/9 python 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 python Day6 面向对象学习 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

面向過程 VS 面向?qū)ο?/h3>

編程范式

編程是 程序 員 用特定的語(yǔ)法+數(shù)據(jù)結(jié)構(gòu)+算法組成的代碼來(lái)告訴計(jì)算機(jī)如何執(zhí)行任務(wù)的過程 , 一個(gè)程序是程序員為了得到一個(gè)任務(wù)結(jié)果而編寫的一組指令的集合,正所謂條條大路通羅馬,實(shí)現(xiàn)一個(gè)任務(wù)的方式有很多種不同的方式, 對(duì)這些不同的編程方式的特點(diǎn)進(jìn)行歸納總結(jié)得出來(lái)的編程方式類別,即為編程范式。 不同的編程范式本質(zhì)上代表對(duì)各種類型的任務(wù)采取的不同的解決問題的思路, 大多數(shù)語(yǔ)言只支持一種編程范式,當(dāng)然也有些語(yǔ)言可以同時(shí)支持多種編程范式。 兩種最重要的編程范式分別是面向過程編程和面向?qū)ο缶幊獭?/p>

面向過程編程(Procedural Programming)
Procedural programming uses a list of instructions to tell the computer what to do step-by-step.
面向過程編程依賴 - 你猜到了- procedures,一個(gè)procedure包含一組要被進(jìn)行計(jì)算的步驟, 面向過程又被稱為top-down languages, 就是程序從上到下一步步執(zhí)行,一步步從上到下,從頭到尾的解決問題 。基本設(shè)計(jì)思路就是程序一開始是要著手解決一個(gè)大的問題,然后把一個(gè)大問題分解成很多個(gè)小問題或子過程,這些子過程再執(zhí)行的過程再繼續(xù)分解直到小問題足夠簡(jiǎn)單到可以在一個(gè)小步驟范圍內(nèi)解決。

這樣做的問題也是顯而易見的,就是如果你要對(duì)程序進(jìn)行修改,對(duì)你修改的那部分有依賴的各個(gè)部分你都也要跟著修改, 舉個(gè)例子,如果程序開頭你設(shè)置了一個(gè)變量值 為1 , 但如果其它子過程依賴這個(gè)值 為1的變量才能正常運(yùn)行,那如果你改了這個(gè)變量,那這個(gè)子過程你也要修改,假如又有一個(gè)其它子程序依賴這個(gè)子過程 , 那就會(huì)發(fā)生一連串的影響,隨著程序越來(lái)越大, 這種編程方式的維護(hù)難度會(huì)越來(lái)越高。
所以我們一般認(rèn)為, 如果你只是寫一些簡(jiǎn)單的腳本,去做一些一次性任務(wù),用面向過程的方式是極好的,但如果你要處理的任務(wù)是復(fù)雜的,且需要不斷迭代和維護(hù) 的, 那還是用面向?qū)ο笞罘奖懔恕?

?

面向?qū)ο缶幊?/h4>

OOP編程是利用“類”和“對(duì)象”來(lái)創(chuàng)建各種模型來(lái)實(shí)現(xiàn)對(duì)真實(shí)世界的描述,使用面向?qū)ο缶幊痰脑蛞环矫媸且驗(yàn)樗梢允钩绦虻木S護(hù)和擴(kuò)展變得更簡(jiǎn)單,并且可以大大提高程序開發(fā)效率 ,另外,基于面向?qū)ο蟮某绦蚩梢允顾烁尤菀桌斫饽愕拇a邏輯,從而使團(tuán)隊(duì)開發(fā)變得更從容。

面向?qū)ο蟮膸讉€(gè)核心特性如下

Class 類
一個(gè)類即是對(duì)一類擁有相同屬性的對(duì)象的抽象、藍(lán)圖、原型。在類中定義了這些對(duì)象的都具備的屬性(variables(data))、共同的方法

Object 對(duì)象
一個(gè)對(duì)象即是一個(gè)類的實(shí)例化后實(shí)例,一個(gè)類必須經(jīng)過實(shí)例化后方可在程序中調(diào)用,一個(gè)類可以實(shí)例化多個(gè)對(duì)象,每個(gè)對(duì)象亦可以有不同的屬性,就像人類是指所有人,每個(gè)人是指具體的對(duì)象,人與人之前有共性,亦有不同

Encapsulation 封裝
在類中對(duì)數(shù)據(jù)的賦值、內(nèi)部調(diào)用對(duì)外部用戶是透明的,這使類變成了一個(gè)膠囊或容器,里面包含著類的數(shù)據(jù)和方法

Inheritance 繼承
一個(gè)類可以派生出子類,在這個(gè)父類里定義的屬性、方法自動(dòng)被子類繼承

Polymorphism 多態(tài)
態(tài)是面向?qū)ο蟮闹匾匦?簡(jiǎn)單點(diǎn)說(shuō):“一個(gè)接口,多種實(shí)現(xiàn)”,指一個(gè)基類中派生出了不同的子類,且每個(gè)子類在繼承了同樣的方法名的同時(shí)又對(duì)父類的方法做了不同的實(shí)現(xiàn),這就是同一種事物表現(xiàn)出的多種形態(tài)。
編程其實(shí)就是一個(gè)將具體世界進(jìn)行抽象化的過程,多態(tài)就是抽象化的一種體現(xiàn),把一系列具體事物的共同點(diǎn)抽象出來(lái), 再通過這個(gè)抽象的事物, 與不同的具體事物進(jìn)行對(duì)話。
對(duì)不同類的對(duì)象發(fā)出相同的消息將會(huì)有不同的行為。比如,你的老板讓所有員工在九點(diǎn)鐘開始工作, 他只要在九點(diǎn)鐘的時(shí)候說(shuō):“開始工作”即可,而不需要對(duì)銷售人員說(shuō):“開始銷售工作”,對(duì)技術(shù)人員說(shuō):“開始技術(shù)工作”, 因?yàn)椤皢T工”是一個(gè)抽象的事物, 只要是員工就可以開始工作,他知道這一點(diǎn)就行了。至于每個(gè)員工,當(dāng)然會(huì)各司其職,做各自的工作。
多態(tài)允許將子類的對(duì)象當(dāng)作父類的對(duì)象使用,某父類型的引用指向其子類型的對(duì)象,調(diào)用的方法是該子類型的方法。這里引用和調(diào)用方法的代碼編譯前就已經(jīng)決定了,而引用所指向的對(duì)象可以在運(yùn)行期間動(dòng)態(tài)綁定。

面向?qū)ο缶幊?Object-Oriented Programming?)介紹

對(duì)于編程語(yǔ)言的初學(xué)者來(lái)講,OOP不是一個(gè)很容易理解的編程方式,大家雖然都按老師講的都知道OOP的三大特性是繼承、封裝、多態(tài),并且大家也都知道了如何定義類、方法等面向?qū)ο蟮某S谜Z(yǔ)法,但是一到真正寫程序的時(shí)候,還是很多人喜歡用函數(shù)式編程來(lái)寫代碼,特別是初學(xué)者,很容易陷入一個(gè)窘境就是“我知道面向?qū)ο?#xff0c;我也會(huì)寫類,但我依然沒發(fā)現(xiàn)在使用了面向?qū)ο蠛?#xff0c;對(duì)我們的程序開發(fā)效率或其它方面帶來(lái)什么好處,因?yàn)槲沂褂煤瘮?shù)編程就可以減少重復(fù)代碼并做到程序可擴(kuò)展了,為啥子還用面向?qū)ο?#xff1f;”。 對(duì)于此,我個(gè)人覺得原因應(yīng)該還是因?yàn)槟銢]有充分了解到面向?qū)ο竽軒?lái)的好處,今天我就寫一篇關(guān)于面向?qū)ο蟮娜腴T文章,希望能幫大家更好的理解和使用面向?qū)ο缶幊獭?? 無(wú)論用什么形式來(lái)編程,我們都要明確記住以下原則:
  • 寫重復(fù)代碼是非常不好的低級(jí)行為
  • 你寫的代碼需要經(jīng)常變更?
  • 開發(fā)正規(guī)的程序跟那種寫個(gè)運(yùn)行一次就扔了的小腳本一個(gè)很大不同就是,你的代碼總是需要不斷的更改,不是修改bug就是添加新功能等,所以為了日后方便程序的修改及擴(kuò)展,你寫的代碼一定要遵循易讀、易改的原則(專業(yè)數(shù)據(jù)叫可讀性好、易擴(kuò)展)。 如果你把一段同樣的代碼復(fù)制、粘貼到了程序的多個(gè)地方以實(shí)現(xiàn)在程序的各個(gè)地方調(diào)用 這個(gè)功能,那日后你再對(duì)這個(gè)功能進(jìn)行修改時(shí),就需要把程序里多個(gè)地方都改一遍,這種寫程序的方式是有問題的,因?yàn)槿绻悴恍⌒穆┑袅艘粋€(gè)地方?jīng)]改,那可能會(huì)導(dǎo)致整個(gè)程序的運(yùn)行都 出問題。 因此我們知道 在開發(fā)中一定要努力避免寫重復(fù)的代碼,否則就相當(dāng)于給自己再挖坑。 還好,函數(shù)的出現(xiàn)就能幫我們輕松的解決重復(fù)代碼的問題,對(duì)于需要重復(fù)調(diào)用的功能,只需要把它寫成一個(gè)函數(shù),然后在程序的各個(gè)地方直接調(diào)用這個(gè)函數(shù)名就好了,并且當(dāng)需要修改這個(gè)功能時(shí),只需改函數(shù)代碼,然后整個(gè)程序就都更新了。 暫不考慮開發(fā)場(chǎng)地等復(fù)雜的東西,我們先從人物角色下手, 角色很簡(jiǎn)單,就倆個(gè),恐怖份子、警察,他們除了角色不同,其它基本都 一樣,每個(gè)人都有生命值、武器等。 咱們先用非OOP的方式寫出游戲的基本角色。 #role 1 name = 'Ben' role = 'terrorist' weapon = 'AK47' life_value = 100#rolw 2 name2 = 'Jack' role2 = 'police' weapon2 = 'B22' life_value2 = 100 上面定義了一個(gè)恐怖份子Ben和一個(gè)警察Jack,但只2個(gè)人不好玩呀,一干就死了,沒意思,那我們?cè)俜謩e一個(gè)恐怖分子和警察吧, #role 1 name = 'Alex' role = 'terrorist' weapon = 'AK47' life_value = 100 money = 10000#rolw 2 name2 = 'Ben' role2 = 'police' weapon2 = 'B22' life_value2 = 100 money2 = 10000#role 3 name3 = 'Rain' role3 = 'terrorist' weapon3 = 'C33' life_value3 = 100 money3 = 10000#rolw 4 name4 = 'Eric' role4 = 'police' weapon4 = 'B51' life_value4 = 100 money4 = 10000 4個(gè)角色雖然創(chuàng)建好了,但是有個(gè)問題就是,每創(chuàng)建一個(gè)角色,我都要單獨(dú)命名,name1,name2,name3,name4…,后面的調(diào)用的時(shí)候這個(gè)變量名你還都得記著,要是再讓多加幾個(gè)角色,估計(jì)調(diào)用時(shí)就很容易弄混啦,所以我們想一想,能否所有的角色的變量名都是一樣的,但調(diào)用的時(shí)候又能區(qū)分開分別是誰(shuí)? 當(dāng)然可以,我們只需要把上面的變量改成字典的格式就可以啦。 roles = { 1:{'name':'Ben', 'role':'terrorist', 'weapon':'AK47', 'life_value': 100, 'money': 15000, }, 2:{'name':'Jack', 'role':'police', 'weapon':'B22', 'life_value': 100, 'money': 15000, }, 3:{'name':'Rain', 'role':'terrorist', 'weapon':'C33', 'life_value': 100, 'money': 15000, }, 4:{'name':'Eirc', 'role':'police', 'weapon':'B51', 'life_value': 100, 'money': 15000, }, } print(roles[1]) #Ben print(roles[2]) #Jack 很好,這個(gè)以后調(diào)用這些角色時(shí)只需要roles[1],roles[2]就可以啦,角色的基本屬性設(shè)計(jì)完了后,我們接下來(lái)為每個(gè)角色開發(fā)以下幾個(gè)功能
  • 被打中后就會(huì)掉血的功能
  • 開槍功能
  • 換子彈
  • 買槍
  • 跑、走、跳、下蹲等動(dòng)作
  • 保護(hù)人質(zhì)(僅適用于警察)
  • 不能殺同伴
  • 。。。
  • 我們可以把每個(gè)功能寫成一個(gè)函數(shù),類似如下: def shot(by_who): #開了槍后要減子彈數(shù) pass def got_shot(who): #中槍后要減血 who[‘life_value’] -= 10pass def buy_gun(who,gun_name): #檢查錢夠不夠,買了槍后要扣錢 pass ... so far so good, 繼續(xù)按照這個(gè)思路設(shè)計(jì),再完善一下代碼,游戲的簡(jiǎn)單版就出來(lái)了,但是在往下走之前,我們來(lái)看看上面的這種代碼寫法有沒有問題,至少?gòu)纳厦娴拇a設(shè)計(jì)中,我看到以下幾點(diǎn)缺陷:
  • 每個(gè)角色定義的屬性名稱是一樣的,但這種命名規(guī)則是我們自己約定的,從程序上來(lái)講,并沒有進(jìn)行屬性合法性檢測(cè),也就是說(shuō)role 1定義的代表武器的屬性是weapon, role 2 ,3,4也是一樣的,不過如果我在新增一個(gè)角色時(shí)不小心把weapon 寫成了wepon , 這個(gè)程序本身是檢測(cè) 不到的
  • terrorist 和police這2個(gè)角色有些功能是不同的,比如police是不能殺人質(zhì)的,但是terrorist可能,隨著這個(gè)游戲開發(fā)的更復(fù)雜,我們會(huì)發(fā)現(xiàn)這2個(gè)角色后續(xù)有更多的不同之處, 但現(xiàn)在的這種寫法,我們是沒辦法 把這2個(gè)角色適用的功能區(qū)分開來(lái)的,也就是說(shuō),每個(gè)角色都可以直接調(diào)用任意功能,沒有任何限制。
  • 我們?cè)谏厦娑x了got_shot()后要減血,也就是說(shuō)減血這個(gè)動(dòng)作是應(yīng)該通過被擊中這個(gè)事件來(lái)引起的,我們調(diào)用get_shot(),got_shot()這個(gè)函數(shù)再調(diào)用每個(gè)角色里的life_value變量來(lái)減血。 但其實(shí)我不通過got_shot(),直接調(diào)用角色roles[role_id][‘life_value’] 減血也可以呀,但是如果這樣調(diào)用的話,那可以就是簡(jiǎn)單粗暴啦,因?yàn)闇p血之前其它還應(yīng)該判斷此角色是否穿了防彈衣等,如果穿了的話,傷害值肯定要減少,got_shot()函數(shù)里就做了這樣的檢測(cè),你這里直接繞過的話,程序就亂了。 因此這里應(yīng)該設(shè)計(jì) 成除了通過got_shot(),其它的方式是沒有辦法給角色減血的,不過在上面的程序設(shè)計(jì)里,是沒有辦法實(shí)現(xiàn)的。?
  • 現(xiàn)在需要給所有角色添加一個(gè)可以穿防彈衣的功能,那很顯然你得在每個(gè)角色里放一個(gè)屬性來(lái)存儲(chǔ)此角色是否穿 了防彈衣,那就要更改每個(gè)角色的代碼,給添加一個(gè)新屬性,這樣太low了,不符合代碼可復(fù)用的原則
  • 上面這4點(diǎn)問題如果不解決,以后肯定會(huì)引出更大的坑,有同學(xué)說(shuō)了,解決也不復(fù)雜呀,直接在每個(gè)功能調(diào)用時(shí)做一下角色判斷啥就好了,沒錯(cuò),你要非得這么霸王硬上弓的搞也肯定是可以實(shí)現(xiàn)的,那你自己就開發(fā)相應(yīng)的代碼來(lái)對(duì)上面提到的問題進(jìn)行處理好啦。 但這些問題其實(shí)能過OOP就可以很簡(jiǎn)單的解決。? 之前的代碼改成用OOP中的“類”來(lái)實(shí)現(xiàn)的話如下: class Role(object): def __init__(self,name,role,weapon,life_value=100,money=15000): self.name = name self.role = role self.weapon = weapon self.life_value = life_value self.money = money def shot(self): print("shooting...") def got_shot(self): print("ah...,I got shot...") def buy_gun(self,gun_name): print("just bought %s" %gun_name) r1 = Role('Ben','police','AK47’) #生成一個(gè)角色 r2 = Role('Jack','terrorist','B22’) #生成一個(gè)角色 先不考慮語(yǔ)法細(xì)節(jié),相比函數(shù)式寫法,上面用面向?qū)ο笾械念悂?lái)寫最直接的改進(jìn)有以下2點(diǎn):
  • 代碼量少了近一半
  • 角色和它所具有的功能可以一目了然看出來(lái)
  • 接下來(lái)我們一起分解一下上面的代碼分別 是什么意思 class Role(object): #定義一個(gè)類, class是定義類的語(yǔ)法,Role是類名,(object)是新式類的寫法,必須這樣寫,以后再講為什么 def __init__(self,name,role,weapon,life_value=100,money=15000): #初始化函數(shù),在生成一個(gè)角色時(shí)要初始化的一些屬性就填寫在這里 self.name = name #__init__中的第一個(gè)參數(shù)self,和這里的self都 是什么意思? 看下面解釋 self.role = role self.weapon = weapon self.life_value = life_value self.money = money 上面的這個(gè)__init__()叫做初始化方法(或構(gòu)造方法), 在類被調(diào)用時(shí),這個(gè)方法(雖然它是函數(shù)形式,但在類中就不叫函數(shù)了,叫方法)會(huì)自動(dòng)執(zhí)行,進(jìn)行一些初始化的動(dòng)作,所以我們這里寫的__init__(self,name,role,weapon,life_value=100,money=15000)就是要在創(chuàng)建一個(gè)角色時(shí)給它設(shè)置這些屬性,那么這第一個(gè)參數(shù)self是干毛用的呢?? 初始化一個(gè)角色,就需要調(diào)用這個(gè)類一次: r1 = Role('Ben','police','AK47’) #生成一個(gè)角色 , 會(huì)自動(dòng)把參數(shù)傳給Role下面的__init__(...)方法 r2 = Role('Jack','terrorist','B22’) #生成一個(gè)角色

    我們看到,上面的創(chuàng)建角色時(shí),我們并沒有給__init__傳值,程序也沒未報(bào)錯(cuò),是因?yàn)?#xff0c;類在調(diào)用它自己的__init__(…)時(shí)自己幫你給self參數(shù)賦值了,

    r1 = Role('Ben','police','AK47’) #此時(shí)self 相當(dāng)于 r1 , Role(r1,'Ben','police','AK47’) r2 = Role('Jack','terrorist','B22’)#此時(shí)self 相當(dāng)于 r2, Role(r2,'Jack','terrorist','B22’) 為什么這樣子?你拉著我說(shuō)你有些猶豫,怎么會(huì)這樣子? 你執(zhí)行r1?=?Role('Ben','police','AK47')時(shí),python的解釋器其實(shí)干了兩件事:
  • 在內(nèi)存中開辟一塊空間指向r1這個(gè)變量名
  • 調(diào)用Role這個(gè)類并執(zhí)行其中的__init__(…)方法,相當(dāng)于Role.__init__(r1,'Ben','police',AK47’),這么做是為什么呢? 是為了把'Alex','police',’AK47’這3個(gè)值跟剛開辟的r1關(guān)聯(lián)起來(lái),是為了把'Ben','police',’AK47’這3個(gè)值跟剛開辟的r1關(guān)聯(lián)起來(lái),是為了把'Ben','police',’AK47’這3個(gè)值跟剛開辟的r1關(guān)聯(lián)起來(lái),重要的事情說(shuō)3次, 因?yàn)殛P(guān)聯(lián)起來(lái)后,你就可以直接r1.name, r1.weapon 這樣來(lái)調(diào)用啦。所以,為實(shí)現(xiàn)這種關(guān)聯(lián),在調(diào)用__init__方法時(shí),就必須把r1這個(gè)變量也傳進(jìn)去,否則__init__不知道要把那3個(gè)參數(shù)跟誰(shuí)關(guān)聯(lián)呀。
  • 明白了么哥?所以這個(gè)__init__(…)方法里的,self.name = name , self.role = role 等等的意思就是要把這幾個(gè)值 存到r1的內(nèi)存空間里。
  • 如果還不明白的話,哥,去測(cè)試一下智商吧, 應(yīng)該不會(huì)超過70,哈哈。 為了暴露自己的智商,此時(shí)你假裝懂了,但又問, __init__(…)我懂了,但后面的那幾個(gè)函數(shù),噢 不對(duì),后面那幾個(gè)方法 為什么也還需要self參數(shù)么? 不是在初始化角色的時(shí)候 ,就已經(jīng)把角色的屬性跟r1綁定好了么?? good question, 先來(lái)看一下上面類中的一個(gè)buy_gun的方法: def buy_gun(self,gun_name): print(“%s has just bought %s” %(self.name,gun_name) ) 上面這個(gè)方法通過類調(diào)用的話要寫成如下: r1 = Role('Ben','police','AK47') r1.buy_gun("B21”) #python 會(huì)自動(dòng)幫你轉(zhuǎn)成 Role.buy_gun(r1,”B21")

    ?

    執(zhí)行結(jié)果 #Ben has just bought B21? 依然沒給self傳值 ,但Python還是會(huì)自動(dòng)的幫你把r1 賦值給self這個(gè)參數(shù), 為什么呢? 因?yàn)?#xff0c;你在buy_gun(..)方法中可能要訪問r1的一些其它屬性呀, 比如這里就訪問 了r1的名字,怎么訪問呢?你得告訴這個(gè)方法呀,于是就把r1傳給了這個(gè)self參數(shù),然后在buy_gun里調(diào)用 self.name 就相當(dāng)于調(diào)用r1.name 啦,如果還想知道r1的生命值 有多少,直接寫成self.life_value就可以了。 說(shuō)白了就是在調(diào)用類中的一個(gè)方法時(shí),你得告訴人家你是誰(shuí)。 好啦, 總結(jié)一下2點(diǎn):
  • 上面的這個(gè)r1?=?Role('Ben','police','AK47)動(dòng)作,叫做類的“實(shí)例化”, 就是把一個(gè)虛擬的抽象的類,通過這個(gè)動(dòng)作,變成了一個(gè)具體的對(duì)象了, 這個(gè)對(duì)象就叫做實(shí)例
  • 剛才定義的這個(gè)類體現(xiàn)了面向?qū)ο蟮牡谝粋€(gè)基本特性,封裝,其實(shí)就是使用構(gòu)造方法將內(nèi)容封裝到某個(gè)具體對(duì)象中,然后通過對(duì)象直接或者self間接獲取被封裝的內(nèi)容
  • 面向?qū)ο蟮奶匦?#xff1a;

    封裝

    封裝最好理解了。封裝是面向?qū)ο蟮奶卣髦?#xff0c;是對(duì)象和類概念的主要特性。

    封裝,也就是把客觀事物封裝成抽象的類,并且類可以把自己的數(shù)據(jù)和方法只讓可信的類或者對(duì)象操作,對(duì)不可信的進(jìn)行信息隱藏。

    繼承

    面向?qū)ο缶幊?(OOP) 語(yǔ)言的一個(gè)主要功能就是“繼承”。繼承是指這樣一種能力:它可以使用現(xiàn)有類的所有功能,并在無(wú)需重新編寫原來(lái)的類的情況下對(duì)這些功能進(jìn)行擴(kuò)展。

    通過繼承創(chuàng)建的新類稱為“子類”或“派生類”。

    被繼承的類稱為“基類”、“父類”或“超類”。

    繼承的過程,就是從一般到特殊的過程。

    要實(shí)現(xiàn)繼承,可以通過“繼承”(Inheritance)和“組合”(Composition)來(lái)實(shí)現(xiàn)。

    在某些 OOP 語(yǔ)言中,一個(gè)子類可以繼承多個(gè)基類。但是一般情況下,一個(gè)子類只能有一個(gè)基類,要實(shí)現(xiàn)多重繼承,可以通過多級(jí)繼承來(lái)實(shí)現(xiàn)。

    繼承概念的實(shí)現(xiàn)方式有三類:實(shí)現(xiàn)繼承、接口繼承和可視繼承。

    ??????????實(shí)現(xiàn)繼承是指使用基類的屬性和方法而無(wú)需額外編碼的能力; ??????????接口繼承是指僅使用屬性和方法的名稱、但是子類必須提供實(shí)現(xiàn)的能力; ??????????可視繼承是指子窗體(類)使用基窗體(類)的外觀和實(shí)現(xiàn)代碼的能力。

    在考慮使用繼承時(shí),有一點(diǎn)需要注意,那就是兩個(gè)類之間的關(guān)系應(yīng)該是“屬于”關(guān)系。例如,Employee 是一個(gè)人,Manager 也是一個(gè)人,因此這兩個(gè)類都可以繼承 Person 類。但是 Leg 類卻不能繼承 Person 類,因?yàn)橥炔⒉皇且粋€(gè)人。

    抽象類僅定義將由子類創(chuàng)建的一般屬性和方法。

    OO開發(fā)范式大致為:劃分對(duì)象→抽象類→將類組織成為層次化結(jié)構(gòu)(繼承和合成) →用類與實(shí)例進(jìn)行設(shè)計(jì)和實(shí)現(xiàn)幾個(gè)階段。

    繼承示例 #!_*_coding:utf-8_*_ class SchoolMember(object): members = 0 #初始學(xué)校人數(shù)為0 def __init__(self,name,age): self.name = name self.age = age def tell(self): passdef enroll(self): '''注冊(cè)'''SchoolMember.members +=1print("\033[32;1mnew member [%s] is enrolled,now there are [%s] members.\033[0m " %(self.name,SchoolMember.members)) def __del__(self): '''析構(gòu)方法'''print("\033[31;1mmember [%s] is dead!\033[0m" %self.name) class Teacher(SchoolMember): def __init__(self,name,age,course,salary): super(Teacher,self).__init__(name,age) self.course = course self.salary = salary self.enroll() def teaching(self): '''講課方法'''print("Teacher [%s] is teaching [%s] for class [%s]" %(self.name,self.course,'s12')) def tell(self): '''自我介紹方法'''msg = '''Hi, my name is [%s], works for [%s] as a [%s] teacher !''' %(self.name,'Oldboy', self.course) print(msg) class Student(SchoolMember): def __init__(self, name,age,grade,sid): super(Student,self).__init__(name,age) self.grade = grade self.sid = sid self.enroll() def tell(self): '''自我介紹方法'''msg = '''Hi, my name is [%s], I'm studying [%s] in [%s]!''' %(self.name, self.grade,'Oldboy') print(msg) if __name__ == '__main__': t1 = Teacher("Ben",22,'Python',20000) t2 = Teacher("Jack",29,'Linux',3000) s1 = Student("helln", 24,"Python S12",1483) s2 = Student("Sam", 26,"Python S12",1484) t1.teaching() t2.teaching() t1.tell() View Code

    多態(tài)

    多態(tài)性(polymorphisn)是允許你將父對(duì)象設(shè)置成為和一個(gè)或更多的他的子對(duì)象相等的技術(shù),賦值之后,父對(duì)象就可以根據(jù)當(dāng)前賦值給它的子對(duì)象的特性以不同的方式運(yùn)作。簡(jiǎn)單的說(shuō),就是一句話:允許將子類類型的指針賦值給父類類型的指針。 那么,多態(tài)的作用是什么呢?我們知道,封裝可以隱藏實(shí)現(xiàn)細(xì)節(jié),使得代碼模塊化;繼承可以擴(kuò)展已存在的代碼模塊(類);它們的目的都是為了——代碼重用。而多態(tài)則是為了實(shí)現(xiàn)另一個(gè)目的——接口重用!多態(tài)的作用,就是為了類在繼承和派生的時(shí)候,保證使用“家譜”中任一類的實(shí)例的某一屬性時(shí)的正確調(diào)用。 ? Pyhon不直接支持多態(tài),但可以間接實(shí)現(xiàn) 通過Python模擬的多態(tài) class Animal: def __init__(self, name): # Constructor of the class self.name = name def talk(self): # Abstract method, defined by convention only raise NotImplementedError("Subclass must implement abstract method") class Cat(Animal): def talk(self): return 'Meow!'class Dog(Animal): def talk(self): return 'Woof! Woof!'animals = [Cat('Missy'), Dog('Lassie')] for animal in animals: print animal.name + ': ' + animal.talk()

    ?

    ?

    ?

    ?

    ?

    轉(zhuǎn)載于:https://www.cnblogs.com/jock911/p/5831169.html

    總結(jié)

    以上是生活随笔為你收集整理的python Day6 面向对象学习的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。