Python基礎之面向對象編程(二)

本篇文章主要介紹面向對象編程。

面向對象編程

幾個定義

  • 面向過程編程:圍繞函數,編寫能處理數據的代碼塊的編程方式。
  • 類、對象:面向對象編程的兩個主要方面。一個類(Class)能創建一種新的類型;對象(Object)是類的實例。可這樣類比:你可擁有類型 int 的變量,也即,存儲整數的變量是 int類 的對象實例。
  • 字段、方法和屬性:從屬于對象或類的變量叫字段(Field);對象調用從屬于類的函數實現某些功能,這些函數叫類的方法(Method);字段和方法統稱為累的屬性(Attribute)。

Tips: 不同于靜態語言,Python 中即使是整數也會被視為對象(int類的對象),同 Java 中裝箱與拆箱概念頗為相似。

類和對象

最簡單的類結構如下所示:

class Student(object):
    pass # 一個空的代碼塊

# 創建類對象實例
student = Student()
print(student)  
# 打印:<__main__.Student object at 0x101985f28>   

*Tips: *

  • Python 中所有類均繼承自 object;
  • Python 打印對象,默認可查看對象地址。Python 會在它找到的任何空間來存儲對象。
類屬性和實例屬性

方法(Method)

Python 對比于 Java 類方法屬性,有兩個特殊點:

  • 類中定義的所有方法,第一個參數必須是 self;相當于 Java 中的 this 引用;
  • _init_() 方法:在類的對象被實例化時立即運行;相當于 Java 中的構造方法。
    Tips: Python中不存在方法的重載,方法的重載是對同一個方法使用可變參數來實現,這在后面函數參數這塊會提到。

示例代碼如下:

class Student(object):
    count = 0  # 類變量

    def __init__(self, name):
        self.name = name  # 實例變量
    
    def say_hi(self):
        print(r'Hello, I'm', self.name)
        
student = Student('Coral')  
student.say_hi()  
# 打印:Hello, I'm Coral

字段(Field)

Python 中字段有兩種類型——類變量與對象變量,對比上述示例代碼,兩者的區別點如下圖所示:


類變量和實例變量區別.png

因為 Python 是動態語言,可以給類創建的實例動態綁定屬性,那么如何給 實例 綁定屬性?如何給 類 綁定屬性呢?

1)給實例綁定屬性

  • 通過在 _init_ 方法中給 self 綁定屬性,這種屬性所有對象實例均可訪問;
  • 直接給實例綁定,這種屬性只適用于該實例,其他實例不能訪問該屬性。如:
student = Student('Coral')
# grade是給實例動態綁定的屬性,name是通過 self綁定的屬性
student.grade = 90 
print('{} grade = {} '.format(student.name, student.grade)) 

student2 = Student('Jane')
print(student2.grade)
# 這句會拋出:AttributeError: 'Student' object has no attribute 'grade'

2)給類綁定屬性
要讓同一個字段屬性對所有實例均適用,除了 self 綁定,還可以適用 類屬性。

  • 類屬性,直接在 class 中定義屬性,歸整個 Student 類所有,如 count 字段。

Tips: 當 實例屬性 和 類屬性 同名時,實例屬性 優于 類屬性,也即,實力屬性會覆蓋類屬性,所以在項目中要避免使用這種同名變量。

訪問限制

Java 中有四種訪問修飾符,Python 中并沒有指定具體的訪問修飾符,僅是按照一種約定的寫法來,如下圖所示:


訪問限制.png
獲取對象信息

在 Java 中通常會判斷一個對象是什么類型,用 instanceOf 來判斷,Python 中也有判斷對象類型的方法,還可以獲取對象擁有的屬性和方法,這些都是 Python 內置的方法。常見的如下圖所示:


獲取對象信息方法.png

這里重點說下 isinstance() 方法,示例如下:

a = list() # a 是 list 類型
b = Animal() # b 是 Animal 類型
c = Dog()  # c 是 Dog 類型

# 1.判斷一個變量是否是某個類型可以用 isinstance() 判斷:
print('a is list:', isinstance(a, list))     # True
print('b is Animal:', isinstance(b, Animal)) # True
print('c is Dog:', isinstance(c, Dog))       # True
print('c is Animal:', isinstance(c, Animal)) # True

# 2. 能用 type() 判斷的基本類型也可以用 isinstance() 判斷:
print(isinstance('a', str))    # True
print(isinstance(123, int))    # True
print(isinstance(b'a', bytes)) # True

# 3. 另外,isinstance() 還可以判斷一個變量是否是某些類型中的一種:
# 判斷變量是否是 list 或 tuple.
def is_list_or_tuple(x):
    return isinstance(x, (list, tuple))

Tips: 區別于 type,對于 class 繼承關系,不便使用 type();要判斷 class 類型,使用 isinstance() 函數。因為 type() 只能返回對象本身的類型,比如 type(dog) != type(animal), 但是 isinstance(dog, Dog) = isinstance(dog, Animal)。

繼承和多態

Python 中允許多繼承,沒有接口實現的概念。繼承和多態總結點如下:


繼承和多態.png

Python 中沒有方法的重載,但是存在方法的覆蓋,子類可以覆蓋父類方法,也適用于運行時綁定傳入的實例。

關于繼承的幾個問題
  1. 子類 能否繼承 父類綁定的 屬性?(每個類通過 self 或者 給實例動態綁定的 屬性都是該類實例 獨立擁有,跟子類沒有任何關聯?)
    A: 子類不能繼承 父類中通過 self或者 動態綁定的屬性;
  2. 子類 是否只能繼承 父類綁定的 類屬性?
    A:子類能繼承 父類中的 類屬性,在操作該類屬性時,使用 ChildClass.property 訪問該類屬性;
  3. 子類可以繼承 父類的所有方法?
    A:Python 中方法沒有 訪問限制符修飾;
  4. 每個類通過 self 或者 給實例動態綁定的 屬性都是該類實例 獨立擁有,跟子類沒有任何關聯?
    A:是。
  5. 子類和父類有同名的 屬性,優先使用哪個?(避免這種情況,直接繼承使用父類的屬性)
    A:子類優先,但最好不要讓子類屬性和父類屬性同名 。
  6. 子類能否繼承父類中 __xxx 隱藏屬性?
    A:這個可以看做是每個類通過 self 綁定的屬性均屬于本類所有,父類中通過 self 綁定的屬性不管是否是隱藏屬性,子類直接訪問就會拋出:AttributeError: 'Dog' object has no attribute '_BaseClass__name' .
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,825評論 6 546
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,814評論 3 429
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 178,980評論 0 384
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 64,064評論 1 319
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,779評論 6 414
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 56,109評論 1 330
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 44,099評論 3 450
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 43,287評論 0 291
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,799評論 1 338
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,515評論 3 361
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,750評論 1 375
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,221評論 5 365
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,933評論 3 351
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,327評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,667評論 1 296
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,492評論 3 400
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,703評論 2 380

推薦閱讀更多精彩內容