NOTE:文章中的代碼縮進不知道怎么搞,直接粘貼使用會報錯
面向?qū)ο缶幊?Object Oriented Programming簡稱OOP)
- OOP把對象作為程序的基本單元侍筛,一個對象包含了數(shù)據(jù)和操作數(shù)據(jù)的函數(shù)。
- 面向?qū)ο蟮脑O(shè)計思想是抽象出Class柿顶,根據(jù)Class創(chuàng)建Instance
面向?qū)ο蟮娜筇攸c:
- 數(shù)據(jù)封裝
- 繼承
- 多態(tài)
類(Class)和實例(Instance)
- 類是抽象的模板
- 實例是根據(jù)類創(chuàng)建出來的一個個具體的"對象"
note:每個對象都擁有相同的方法游沿,但各自的數(shù)據(jù)可能不同 - 定義類通過
Class
關(guān)鍵字:
class Student(object):
pass
- 類名是大寫字母開頭的單詞,
()
里表示該類是從哪個類繼承下來的雁乡,沒有合適的類就用object
類吐葱,這是所有類最終都會繼承的類
- 創(chuàng)建實例是通過類名+()實現(xiàn)的:
>>> bart = Student()
- 類可以起到模板的作用
可以在創(chuàng)建實例的時候街望,把一些我們認為必須綁定的屬性強制填寫進去,通過定義一個特殊的__init__
方法來實現(xiàn):
class Student(object):
def __init__(self, name, score):
self.name = name
self.score = score
note:__init__
方法的第一個參數(shù)永遠是self
弟跑,表示創(chuàng)建的實例本身灾前,但是在調(diào)用是不用傳遞該參數(shù)。除此之外類的方法和普通函數(shù)沒有什么區(qū)別孟辑,可以使用默認參數(shù)哎甲、可變參數(shù)蔫敲、關(guān)鍵字參數(shù)和命名關(guān)鍵字參數(shù)
數(shù)據(jù)封裝
- 實例本身就擁有數(shù)據(jù),要訪問這些數(shù)據(jù)炭玫,沒有必要從外面的函數(shù)去訪問奈嘿,直接在類的內(nèi)部定義訪問數(shù)據(jù)的函數(shù),這樣吞加,就把“數(shù)據(jù)”給封裝起來了裙犹。
- 這些封裝數(shù)據(jù)的函數(shù)是和類本身是關(guān)聯(lián)起來的,我們稱之為類的方法
- 定義方法
除了第一個參數(shù)是self
外衔憨,其他和普通函數(shù)一樣
class Student(object):
def __init__(self, name, score):
self.name = name
self.score = score
def print_score(self):
print('%s: %s' % (self.name, self.score))
- 調(diào)用方法
只需要在實例變量上直接調(diào)用叶圃,除了self
不用傳遞,其他參數(shù)正常傳入:
>>> bart.print_score()
Bart Simpson: 59
數(shù)據(jù)封裝的優(yōu)勢:
- 調(diào)用容易践图,不用知道內(nèi)部實現(xiàn)的細節(jié)
- 可以給類增加新的方法
訪問限制
- 要讓內(nèi)部屬性不被外部訪問掺冠,可以把屬性的名稱前加上兩個下劃線
__
,實例的變量名如果以__
開頭码党,就變成了一個私有變量(private)德崭,只有內(nèi)部可以訪問,外部不能訪問
note:__xxx__
是特殊變量闽瓢,可以直接訪問接癌,不是private變量心赶,注意區(qū)分
class Student(object):
def __init__(self, name, score):
self.__name = name
self.__score = score
def print_score(self):
print('%s: %s' % (self.__name, self.__score))
- 要想外部訪問內(nèi)部變量扣讼,可以通過給類增加方法來實現(xiàn)
繼承和多態(tài)
在OOP程序設(shè)計中,當我們定義一個class的時候缨叫,可以從某個現(xiàn)有的class繼承椭符,新的class稱為子類(Subclass),而被繼承的class稱為基類耻姥、父類或超類(Base class销钝、Super class)
- 繼承的好處:
- 子類獲得了父類的全部功能
- 我們對代碼做一點改進,子類和父類都存在相同的方法時琐簇,之類的方法會覆蓋父類的方法蒸健,這就是多態(tài)
- 多態(tài)的好處(“開閉原則”):
- 對擴展開放:允許新增子類
- 對修改封閉:不需要修改依賴父類的任何函數(shù)
- 動態(tài)語言的“鴨子類型”
不要求嚴格的繼承體系,一個對象只要“看起來像鴨子婉商,走起路來像鴨子”似忧,那它就可以被看做是鴨子
也就是不同的對象只要有相同的方法,那么就可以認為是一種“類型”
獲取對象信息
type()
-
isinstance()
返回值是True或者False -
dir()
獲得一個對象的所有屬性和方法
- 類似
__xxx__
的屬性和方法在Python中都是有特殊用途的
-
getattr()
丈秩、setattr()
盯捌、hasattr()
- 對于
getattr()
可以傳入一個default參數(shù),如果屬性不存在蘑秽,就返回默認值
>>> getattr(obj, 'z', 404) # 獲取屬性'z'饺著,如果不存在箫攀,返回默認值404
實例屬性和類屬性
- 類的屬性直接在Class中定義,該屬性歸該類所有幼衰,因此所有的實例都可以訪問類的屬性
- 千萬不要把實例屬性和類屬性使用相同的名字靴跛,因為相同名稱的實例屬性將屏蔽掉類屬性