Learn Python 3:類、對象

面向?qū)ο螅∣bject Oriented Programming饼煞,簡稱OOP)中有兩個重要的概念:類(Class)和實例(Instance),類是抽象的模板诗越,而實例是根據(jù)類創(chuàng)建出來的具體“對象”砖瞧。

一、創(chuàng)建類嚷狞、對象

1块促、創(chuàng)建類
class Cat():
    color = 'white'
    """貓的基本特性描述"""
    def __init__(self, name, age):
        """初始化參數(shù)"""
        self.name = name
        self.age = age
        self.sex = 'male'
    
    def catch(self):
        """貓捉老鼠"""
        print(self.name + ' is catching the mouse!')

上邊定義了一個Cat類,首先看__init__()方法(init前后各兩個下劃線)感耙,它是一個特殊方法褂乍,類似java中的構(gòu)造函數(shù),包含三個形參: self即硼、nameage逃片。其中形參self必不可少,還必須位于其他形參的前面,表示創(chuàng)建的實例本身褥实,在__init__方法內(nèi)部呀狼,就是把屬性name、age綁定到實例上的操作损离,則name哥艇、age就是實例屬性,可以通過實例訪問僻澎,其中sex是一個有默認值的實例屬性貌踏。注意color屬性綁定在類本身,屬于類屬性窟勃。

Cat類中有一個catch()方法祖乳,和普通函數(shù)類似,只多了一個必須的self參數(shù)秉氧,和init方法類似眷昆,通過類的實例調(diào)用時也不用傳遞self參數(shù)。

2汁咏、創(chuàng)建對象

創(chuàng)建Cat實例時亚斋, Python將調(diào)用Cat類的方法__init__(),參數(shù)self會自動傳遞攘滩,只需提供name帅刊、age兩個參數(shù):

>>>cat = Cat('tom', 2)
# 訪問name屬性
>>>cat.name
'tom'
# 調(diào)用catch()方法
>>>cat.catch()
tom is catching the mouse!

二、訪問屬性

前邊通過cat實例可以訪問到name屬性漂问,如果不想屬性直接被訪問厚掷,可以這樣修改Cat類:

class Cat():
    def __init__(self, name, age):
        self.__name = name
        self.__age = age

省略了非關(guān)鍵代碼,分別在name级解、age屬性名前加了兩個下劃線__,這樣屬性就被私有化了田绑,再試著訪問一次:

>>>cat = Cat('tom', 2)
>>>cat.__name
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'Student' object has no attribute '__name'

這樣實例屬性就不能被隨意訪問修改了勤哗,代碼更加健壯。
之后要訪問name屬性掩驱,可以提供相應的發(fā)方法:

class Cat():
    def __init__(self, name, age):
        self.__name = name
        self.__age = age

    def get_name(self):
        return self.__name
>>>cat = Cat('tom', 2)
>>>cat.get_name()

如果要修改屬性值芒划,可以增加相應的set方法:

class Cat():
    def __init__(self, name, age):
        self.__name = name
        self.__age = age

    def get_name(self):
        return self.__name

    def set_name(self, name):
        return self.__name = name
>>>cat = Cat('tom', 2)
>>>cat.set_name('bob')

當然屬性前如果沒加雙下劃線,則可以直接修改屬性值:

>>>cat = Cat('tom', 2)
>>>cat.name = 'bob'

前邊提到了實例屬性和類屬性欧穴,在類屬性非私有的條件下民逼,可以直接通過實例訪問類屬性,如果存在同名的實例屬性和類屬性則實例屬性將屏蔽掉類屬性涮帘。

三拼苍、繼承

先創(chuàng)建父類Animal:

class Animal():
    def __init__(self, color):
        self.color= color
    
    def slogan(self):
        print('Animals are friends of human!')

再創(chuàng)建Dog子類繼承Animal:

class Dog(Animal):
    def __init__(self, name, sex, color):
        super().__init__(color)
        self.name= name
        self.sex = sex
    
    def slogan(self):
        print('Dogs are friends of human!')
    
    def run(self):
        print(self.name + ' is running!')

其中name、sex调缨、run()分別是子類的屬性和方法疮鲫。同時重寫了父類的slogan()方法吆你。

定義子類時,必須在括號內(nèi)指定父類的名稱俊犯。super()是一個特殊函數(shù)妇多,幫助Python將父類和子類關(guān)聯(lián)起來,super().__init__(name, age)會調(diào)用
Dog的父類的方法__init__()燕侠,讓Dog的實例包含父類的所有屬性者祖。

通過繼承,子類獲得了父類的全部非私有功能:

>>>dog1 = Dog('kk', 'male', 'yellow')
>>>dog1.name
'kk'
>>>dog1.slogan()
Dogs are friends of human!
>>>dog1.run()
kk is running!

Python是支持多重繼承的绢彤!

四七问、多態(tài)

以上邊的例子為基礎(chǔ):

>>>a = Animal('white')
>>>d = Dog('kk', 'male', 'white')
>>>isinstance(a, Animal)
True
>>>isinstance(d, Dog)
True
>>>isinstance(d, Animal)
True
>>>isinstance(a, Dog)
False

isinstance()方法可以判斷一個實例的類型。
從上邊的例子可以看出杖虾,d是Dog類型也是Animal類型烂瘫,但是a不是Dog類型。所以奇适,如果一個實例的類型是某個子類坟比,那它的類型也可以被看做是父類,但反過來就不行嚷往。這就是多態(tài)的體現(xiàn)葛账。

再看一個例子:

def show_slogan(animal):
    animal.slogan()
>>>a = Animal('white')
>>>d = Dog('kk', 'male', 'white')
>>>show_slogan(a)
Animals are friends of human!
>>>show_slogan(d)
Dogs are friends of human!

什么意思呢?因為Dog是Animal的子類皮仁,都有run()方法籍琳,因此調(diào)用show_slogan()方法時只要傳入Animal類或者子類的實例,就會自動調(diào)用實際類型的run()方法贷祈。因為多態(tài)的存在趋急,新增一種Animal的子類時,只要確保run()方法編寫正確势誊,show_slogan()就可以正常執(zhí)行呜达。

五、鴨子類型

在靜態(tài)語言中粟耻,例如Java查近,如果需要傳入Animal類型,則傳入的對象必須是Animal類型或者其子類挤忙,否則將無法調(diào)用run()方法霜威。然而對于Python這樣的動態(tài)語言來說,則不一定要傳入Animal類型的對象册烈,只需保證傳入的對象有一個run()方法就可以了戈泼。

這就是動態(tài)語言的“鴨子類型”,它并不要求嚴格的繼承體系,一個對象只要“看起來像鴨子矮冬,走起路來像鴨子”谈宛,那它就可以被看做是鴨子。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末胎署,一起剝皮案震驚了整個濱河市吆录,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌琼牧,老刑警劉巖恢筝,帶你破解...
    沈念sama閱讀 212,383評論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異巨坊,居然都是意外死亡撬槽,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,522評論 3 385
  • 文/潘曉璐 我一進店門趾撵,熙熙樓的掌柜王于貴愁眉苦臉地迎上來侄柔,“玉大人,你說我怎么就攤上這事占调≡萏猓” “怎么了?”我有些...
    開封第一講書人閱讀 157,852評論 0 348
  • 文/不壞的土叔 我叫張陵究珊,是天一觀的道長薪者。 經(jīng)常有香客問我,道長剿涮,這世上最難降的妖魔是什么言津? 我笑而不...
    開封第一講書人閱讀 56,621評論 1 284
  • 正文 為了忘掉前任,我火速辦了婚禮取试,結(jié)果婚禮上悬槽,老公的妹妹穿的比我還像新娘。我一直安慰自己瞬浓,他們只是感情好陷谱,可當我...
    茶點故事閱讀 65,741評論 6 386
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著瑟蜈,像睡著了一般。 火紅的嫁衣襯著肌膚如雪渣窜。 梳的紋絲不亂的頭發(fā)上铺根,一...
    開封第一講書人閱讀 49,929評論 1 290
  • 那天,我揣著相機與錄音乔宿,去河邊找鬼位迂。 笑死,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的掂林。 我是一名探鬼主播臣缀,決...
    沈念sama閱讀 39,076評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼泻帮!你這毒婦竟也來了精置?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,803評論 0 268
  • 序言:老撾萬榮一對情侶失蹤锣杂,失蹤者是張志新(化名)和其女友劉穎脂倦,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體元莫,經(jīng)...
    沈念sama閱讀 44,265評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡赖阻,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,582評論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了踱蠢。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片火欧。...
    茶點故事閱讀 38,716評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖茎截,靈堂內(nèi)的尸體忽然破棺而出苇侵,到底是詐尸還是另有隱情,我是刑警寧澤稼虎,帶...
    沈念sama閱讀 34,395評論 4 333
  • 正文 年R本政府宣布衅檀,位于F島的核電站,受9級特大地震影響霎俩,放射性物質(zhì)發(fā)生泄漏哀军。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 40,039評論 3 316
  • 文/蒙蒙 一打却、第九天 我趴在偏房一處隱蔽的房頂上張望杉适。 院中可真熱鬧,春花似錦柳击、人聲如沸猿推。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,798評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽蹬叭。三九已至,卻和暖如春状知,著一層夾襖步出監(jiān)牢的瞬間秽五,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,027評論 1 266
  • 我被黑心中介騙來泰國打工饥悴, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留坦喘,地道東北人盲再。 一個月前我還...
    沈念sama閱讀 46,488評論 2 361
  • 正文 我出身青樓,卻偏偏與公主長得像瓣铣,于是被迫代替她去往敵國和親答朋。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 43,612評論 2 350

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