Python面向?qū)ο缶幊蹋∣bject Oriented Programming)之類定義及繼承

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

面向過程編程和對象編程都是程序設(shè)計思想押框,面向過程程序設(shè)計是將需要實(shí)現(xiàn)的功能流程化列出來岔绸,讓程序依次按照命令執(zhí)行。跟面向過程程序設(shè)計不同橡伞,面向?qū)ο缶幊淌菍F(xiàn)實(shí)中的個體的狀態(tài)和行為抽象化成對象的屬性和方法盒揉,通過對象間的方法進(jìn)行信息處理和通信模擬現(xiàn)實(shí)世界中的實(shí)體交互,高度抽象的設(shè)計思想可以模擬現(xiàn)實(shí)中的情景和需求兑徘,更方便地面對大型程序設(shè)計的需要刚盈。
Python是一門面向?qū)ο缶幊痰恼Z言,其將所有的數(shù)據(jù)類型都視為對象挂脑。其中最重要的概念是類和實(shí)例藕漱。類是為某一個現(xiàn)實(shí)對象創(chuàng)建出的模板欲侮,其包含了該對象所擁有的屬性和方法,通過實(shí)例化對類進(jìn)行個性化設(shè)定便創(chuàng)造出實(shí)例肋联。

1.Class 和 Instance

類是作為對象的模板威蕉,可以在里面設(shè)定公共屬性(類屬性)、實(shí)例屬性(對象屬性)橄仍、構(gòu)造器和方法

class Dog(object):
    #類屬性默認(rèn)用大寫命名
    CATEGORY = '犬屬'
    #構(gòu)造器由__init__命名韧涨,括號內(nèi)包括固定參數(shù)self和實(shí)例屬性
    def __init__(self,name,ages):
        self.name = name
        self.__ages = ages
    #方法的括號第一個參數(shù)一定是self,可加其他參數(shù)
    def run(self,state):
        print("狗兒跑得"+state+"侮繁,我叫"+self.name)
    #將屬性復(fù)制功能封裝在函數(shù)中提供了一定的安全性虑粥,并且可以在賦值中添加校準(zhǔn)及其他功能。
    def setAges(self,ages):
        if type(ages) == int:
            self.__ages = ages
        else:
            print("你輸入的不是數(shù)字宪哩,不能充當(dāng)年齡")
    def getAges(self):
        return self.__ages
    
dog = Dog("旺財",12)
print(dog.CATEGORY)
dog.run("慢")
dog.setAges(10)
print(dog.getAges())

結(jié)果為:

>犬屬
>狗兒跑得慢娩贷,我叫旺財
>10

在上面的實(shí)例屬性設(shè)定中出現(xiàn)了__ages這樣子以雙下劃線開頭的屬性定義,這標(biāo)志著是private變量锁孟,不準(zhǔn)許通過實(shí)例.變量的方式來讀取彬祖,這種保護(hù)機(jī)制便確保了外部程序沒辦法隨意修改對象內(nèi)部的狀態(tài)。其實(shí)本質(zhì)上解釋器會將該變量名轉(zhuǎn)化為_Dog__ages在其前面添加上_類名

dog.__ages = 1
# 僅僅是為實(shí)例創(chuàng)建了一個新的屬性而已罗岖,動態(tài)語言確實(shí)可以運(yùn)行時添加屬性
print(dog.getAges())
print(dog.__ages)
# __ages在實(shí)例化時已經(jīng)變成了_Dog__ages
dog._Dog__ages = 13
print(dog.getAges())

結(jié)果是:

>10
>1
>13

注意:有些時候在類定義中出現(xiàn)了了一個下劃線開的實(shí)例變量名涧至,這樣的實(shí)例變量在程序?qū)用嫔鲜强梢哉TL問的,但是按照約定俗成的規(guī)定桑包,這種命名形式是告訴使用者將其看成私有變量南蓬,不要從外面進(jìn)行訪問。

2.類屬性和實(shí)例屬性

類屬性是指該變量歸類所有哑了,所有新創(chuàng)建的實(shí)例都可以訪問得到赘方,但只能通過類名索引的方式來修改勒邊來那個。Python可以在類定義中用self定義實(shí)例變量弱左,作為動態(tài)語言也可以在程序執(zhí)行過程中通過實(shí)例直接創(chuàng)建實(shí)例變量窄陡。

>>> class Dog():
    name = "旺財"

>>> dog = Dog()
# 訪問類變量
>>> dog.name
'旺財'
# 綁定新的實(shí)例屬性
>>> dog.ages = 12
>>> dog.ages
12
# 實(shí)例屬性覆蓋類屬性
>>> dog.name = "耿狗"
>>> dog.name
'耿狗'
# 刪除實(shí)例屬性,重新可以訪問類屬性
>>> del dog.name
>>> dog.name
'旺財'
# 重新定義類屬性
>>> Dog.name = "lal"
>>> Dog.name
'lal'
# 測試是不是真正刪除類屬性
>>> del Dog.name
>>> Dog.name
Traceback (most recent call last):
  File "<pyshell#23>", line 1, in <module>
    Dog.name
AttributeError: type object 'Dog' has no attribute 'name'

python作為動態(tài)語言可以在運(yùn)行過程中為實(shí)例綁定新的實(shí)例屬性(對類和對其他實(shí)例無效)拆火,如上面所示為Dog實(shí)例dog綁定了新的實(shí)例屬性ages跳夭。有時候我們可能希望限制綁定的屬性,python提供了slots特殊類屬性來限定可動態(tài)綁定的實(shí)例屬性们镜,在類定義的時候?qū)⒖赡苄枰獎討B(tài)綁定的實(shí)例屬性名創(chuàng)建成一個元組賦給slots類屬性币叹,綁定除了指定屬性外的實(shí)例屬性將會出現(xiàn)錯誤。

class Dog(object):
    __slots__ = ('name','ages')

dog = Dog()
dog.color = yellow

結(jié)果為:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'Dog' object has no attribute 'color'

3.枚舉類與元類

在python中可以用大寫字母來設(shè)定常量模狭,表明不可修改颈抚,但是這并不是一種語言機(jī)制而是一種自覺機(jī)制,有被篡改的風(fēng)險嚼鹉。在python3.4中添加了枚舉類便于大小一定的特殊類的定義贩汉,如季節(jié)驱富、工作日等。
枚舉類有兩種不同的設(shè)定形式匹舞,一種便是按照類定義的形式繼承Enum類褐鸥,可以在類中自定義的設(shè)定每一個成員的具體值,或者可以用Enum函數(shù)直接對每一個成員自動編排值策菜。

from enum import Enum,unique

# 用@unique使枚舉類成員的值都是唯一的
@unique
class Season(Enum):
    spring = 1
    sunner = 2
    autumn = 3
    winter = 4
# 可以用Eunm函數(shù)直接定義
Season = Enum('Season',('spring','sunner','autumn','winter'))

其中以枚舉類名.成員名的形式來索引每一個成員晶疼,每一個成員都有其名字和值酒贬,可以調(diào)用枚舉類內(nèi)部的members變量來獲取包含全部成員情況的字典

spring = Season.spring
print(spring.name)
print(spring.value)
for name, member in Season.__members__.items():
    print(name, '=>', member, ',', member.value)

輸出:

>spring
>1
>Season.sunner
>spring => Season.spring , 1
>sunner => Season.sunner , 2
>autumn => Season.autumn , 3
>winter => Season.winter , 4
>Season.spring
>Season.sunner
>Season.autumn
>Season.winter

4.繼承與多態(tài)

上面舉的例子Dog類繼承了object類又憨,故object稱為Dog類的Super class,Dog類為Subclass锭吨,子類通過繼承獲得了父類的全部成分蠢莺,并且擁有重新復(fù)寫成分的能力。

class WangCai(Dog):
    def __init__(self,state,name,ages):
        self.state = state
        self.name = name
        self.ages = ages
    def run(self):
        print("我是子類的旺財")
        super().run(self.state)

wangcai = WangCai("慢","旺財",12)
wangcai.run()

結(jié)果為:

>我是子類的旺財
>狗兒跑得慢零如,我叫旺財

多態(tài)一般是指在靜態(tài)類型語言中的子類可以傳入需要父類做參數(shù)的函數(shù)躏将,在運(yùn)行的時候調(diào)用子類的相關(guān)內(nèi)容,包含了編譯時類型和運(yùn)行時類型的概念考蕾。這樣一來原先為父類編寫的方法也可以操作子類,而不需要從新定義新的函數(shù)肖卧,大大降低了開發(fā)成本塞帐。但是其實(shí)像python這種動態(tài)類型的語言葵姥,設(shè)定的參數(shù)并不需要提前設(shè)定類型榔幸,參數(shù)引用的對象是具體運(yùn)行到的時候才定義的,因此在實(shí)際操作時可以靈活很多牍疏。只要滿足函數(shù)中所需的調(diào)用的成分麸澜,就可以充當(dāng)參數(shù)傳入并在函數(shù)內(nèi)部進(jìn)行調(diào)用炊邦。這就是動態(tài)語言的“鴨子類型”,它并不要求嚴(yán)格的繼承體系窄俏,一個對象只要“看起來像鴨子碘菜,走起路來像鴨子”忍啸,那它就可以被看做是鴨子。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末悄晃,一起剝皮案震驚了整個濱河市凿滤,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌眷蚓,老刑警劉巖反番,帶你破解...
    沈念sama閱讀 219,427評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件校读,死亡現(xiàn)場離奇詭異歉秫,居然都是意外死亡雁芙,警方通過查閱死者的電腦和手機(jī)兔甘,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,551評論 3 395
  • 文/潘曉璐 我一進(jìn)店門洞焙,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人熔任,你說我怎么就攤上這事唁情∫商Γ” “怎么了甸鸟?”我有些...
    開封第一講書人閱讀 165,747評論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長抢韭。 經(jīng)常有香客問我薪贫,道長篮绰,這世上最難降的妖魔是什么后雷? 我笑而不...
    開封第一講書人閱讀 58,939評論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮吠各,結(jié)果婚禮上勉抓,老公的妹妹穿的比我還像新娘贾漏。我一直安慰自己纵散,他們只是感情好伍掀,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,955評論 6 392
  • 文/花漫 我一把揭開白布蜜笤。 她就那樣靜靜地躺著盐碱,像睡著了一般瓮顽。 火紅的嫁衣襯著肌膚如雪县好。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,737評論 1 305
  • 那天暖混,我揣著相機(jī)與錄音缕贡,去河邊找鬼。 笑死,一個胖子當(dāng)著我的面吹牛晾咪,可吹牛的內(nèi)容都是我干的黔漂。 我是一名探鬼主播,決...
    沈念sama閱讀 40,448評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼禀酱,長吁一口氣:“原來是場噩夢啊……” “哼炬守!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起剂跟,我...
    開封第一講書人閱讀 39,352評論 0 276
  • 序言:老撾萬榮一對情侶失蹤减途,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后曹洽,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體鳍置,經(jīng)...
    沈念sama閱讀 45,834評論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,992評論 3 338
  • 正文 我和宋清朗相戀三年送淆,在試婚紗的時候發(fā)現(xiàn)自己被綠了税产。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,133評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡偷崩,死狀恐怖辟拷,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情阐斜,我是刑警寧澤衫冻,帶...
    沈念sama閱讀 35,815評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站谒出,受9級特大地震影響隅俘,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜笤喳,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,477評論 3 331
  • 文/蒙蒙 一为居、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧杀狡,春花似錦蒙畴、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,022評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至董朝,卻和暖如春鸠项,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背子姜。 一陣腳步聲響...
    開封第一講書人閱讀 33,147評論 1 272
  • 我被黑心中介騙來泰國打工祟绊, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留楼入,地道東北人。 一個月前我還...
    沈念sama閱讀 48,398評論 3 373
  • 正文 我出身青樓牧抽,卻偏偏與公主長得像嘉熊,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子扬舒,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,077評論 2 355

推薦閱讀更多精彩內(nèi)容