Python面向對象知多少?

問題場景

小王是某遊戲公司的新入職的職員,有一天,組長交給了他一個任務,爲一個即將準開發的一款遊戲設計一些人物角色,其中包括多種職業,如牧師、戰士和法師等等。每種職業都有一些自身獨有的屬性和技能,可是也會有一些共有的屬性和方法。假設這家公司是用 Python 來開發遊戲的。python

經歷過面向對象編程學習的小王很快就理清了思路,這須要用類的思想來進行設計。因爲這些職業都會有一些共有的屬性和方法,顯然應該把這些職業的共有屬性和方法拿出來做爲一個公共的類,而這個公共的類就叫作基類,或者稱爲父類;其它職業能夠基於這個公共的類來進行增長屬性和方法,這些職業的類就叫作子類。這就是面向對象編碼中的繼承的思想,理清了設計思路以後,小王立馬開始動手來實現相應的代碼。git


父類設計

首先,對於每個遊戲角色,它都會有姓名和性別屬性。組長又告訴小王,咱們不能讓其它人知道咱們的角色是怎麼設計的,以及都有哪些屬性,這又該如何設計呢?聰明的小王立馬就想到了封裝的思想,經過隱藏對象的屬性和實現細節能夠防止外部的類直接調用屬性或者修改屬性。因此小王立馬寫出了以下的代碼:github

class Roler(object):
    """
    用戶角色類,須要隱藏屬性
    Args:
        __username: 用戶名,string
        __sex:性別, string
    """
    def __init__(self, name=None, sex="male"):
        self.__username = name
        self.__sex = sex
        self.__hp = 1000

    def get_username(self):
        # 獲取用戶名
        return self.__username

    def get_sex(self):
        # 獲取用戶性別
        return self.__sex

    def add_hp(self, hpr):
        # 角色能夠回血
        self.__hp += hpr

    def __repr__(self):
        # 打印對象信息
        return "username : {0}\nsex : {1}\nhp : {2}".format(self.__username, self.__sex, self.__hp)

不一樣於 JavaC++ ,在 Python 中是沒有 private 等關鍵字的。因此咱們如何來定義一個類的屬性是私有的呢?方法就是在類屬性的名字前加上兩個下劃線,即表示成 __username 的形式,這就是私有屬性的定義方式了。其緣由是由於 Python 的類的內部,全部雙下劃線的開始的名字都會被替換成增長單下劃線和類名的方式。實質上,__username 就被替換成了 _Roler__username 的形式了。編程

role1 = Roler("weisheng", "male") # 創建一個新角色
print(role1) # 打印該角色的信息,調用 __repr__() 方法

print(role1.__username) # AttributeError,該屬性是私有的
print(role1._Roler__username) # weisheng,能夠打印

子類設計

有了父類還不夠,因爲每一個職業都會有一些自身特有的屬性和方法。因此,對於每一個職業,咱們也須要實現一個類。小王首先針對牧師這個職業來實現,牧師做爲一個法系醫療職業,首先確定須要一個 MP 值。同時,它能給其它用戶恢復生命值。所以,能夠按照以下方式來實現牧師類:微信

class Pastor(Roler):
    """
    牧師類,繼承自用戶角色類
    Args:
        __MP: 魔法值
    """
    def __init__(self, name, sex):
        # 調用父類的構造函數
        super().__init__(name, sex)
        self.__mp = 100
    def get_mp(self):
        return self.__mp
    def __repr__(self):
        return super().__repr__() + "\nmp : {0}".format(self.__mp)

    def fullhealth(self, other):
        # 技能1:回覆其它用戶生命值
        other.add_hp(200)

在定義的牧師類中,首先調用父類的構造函數來對用戶姓名、性別、hp值進行初始化。同時,牧師還有個mp值,這個屬性是該職業獨有的(請勿追究細節)。因爲增長了相應的屬性,因此 __repr__() 方法也須要重寫,能夠經過調用父類的 __repr__() 方法再加上牧師類獨有的屬性。函數

子類不能直接調用父類的私有屬性,因此針對父類的一些私有屬性,須要經過方法來調用。學習

牧師還有一個技能,他能給其它的用戶角色回血,因此須要實習一個 fullhealth() 方法,參數是其它的角色類。測試用例以下:測試

pastor1 = Pastor("ergouzi", "male") # 創建一個牧師職業
print(pastor1)  # 打印該職業角色的信息

pastor1.fullhealth(role1)  # 牧師能夠給其餘角色回血
print(role1)  # 能夠發現該用戶的 hp 值發生變化

其餘職業的設計能夠參照該職業的特色來作出相應的設計,這裏就不在多作說明了。編碼


面向對象總結

經過跟隨小王的遊戲角色設計,相信你已經對 Python 中的面向對象編程有了必定的瞭解了。面向對象編程是如今經常使用的一種編程方式,它是相對於面向過程編程來講的。面向對象編程把對象做爲程序的基本單元,一個對象包含了數據和操做數據的函數。該思想最主要的三個特色就是封裝、繼承和多態,其實這些特色在上述的實例中都有體現,你能發現嗎?設計

雖然上述的例子已經闡述了面向對象編程的大部分思想,可是本人也是第一次去進行這些類間關係的設計,因此每一個例子都是很是簡單的,可能在思想設計上也存在問題,請見諒。

所有代碼請訪問:面向對象編程

更多精彩內容將發佈在公衆號 冰咖啡與狗 ,或搜索微信號 icedcoffee7 添加公衆號。

相關文章
相關標籤/搜索