Python面向對象-封裝

前言

在 Python入門基礎中,可能有些知識點沒聽懂扫皱。聽咏尝,你不一定能完全聽懂,但是還是那件事啸罢,不放棄编检,不拋棄,一個點聽不動扰才,好允懂,就是那一個點聽不懂。從戰(zhàn)略上要蔑視那一個點衩匣,繼續(xù)往下走......最后蕾总,總體上的勝利就是成功了。
知識不要糾結一個點琅捏,人生亦是如此生百。認真對待每一個過程,但是不要糾結過不去柄延。

面向過程

關注過程(細節(jié)) “干”

面向對象

關心解決問題的人 “找”
(1)識別對象蚀浆,找人
(2)分配職責,干活 (行為 => 數據)
(3)建立交換,調用

面向對象設計過程例子:

面向對象設計過程例子

理解圖

面向對象設計:先有具體對象市俊,再從具體對象抽象出類杨凑。

面向對象設計
  • OOA: 面向對象分析
  • OOD: 面向對象設計
  • OOP: 面向對象編程
類與對象
  • 類: 抽象的概念
    數據成員:
    行為成員:
    如何劃分“類”?
    兩個字“行為”, 干的事情不同 (函數/方法 不同)
  • 對象: 具體的事物
    數據成員:
    行為成員:
    對象與對象有什么不同摆昧?
    數據不同撩满,我們都知道“對象”內存空間只存儲了“數據成員”
"""
練習1: 面向對象基礎語法

"""


class Wifi:
    # 數據成員
    def __init__(self, name, sex):
        # self 是調用當前方法的對象地址
        self.name = name  # 創(chuàng)建實例變量
        self.sex = sex

    # 行為成員
    def play(self):
        print(self.name + "玩耍") # 調用實例變量


# 創(chuàng)建對象,實際在調用 __init__ 方法
w01 = Wifi("莉莉", "女")  # 自動將對象地址傳入方法
w01.play()  # 自動將對象地址傳入方法


創(chuàng)建實例內存圖
實例成員與類成員

也稱為實例變量與類變量

  • 實例變量
    練習對象的數據成員修改:
    實例成員也就是對象成員绅你,實例成員包括兩種:實例變量 + 實例方法
  • 實例變量語法
    定義:只要遵循 對象.變量名 就是在定義實例變量:
#(1)首次通過對象創(chuàng)建后賦值伺帘。(不鼓勵)
w01 = Wife()
w01.name = "小張"   # 這種語法可以,但是不鼓勵<删狻B贰!
#(2)通常做法是構造函數(__init__)中創(chuàng)建汉规。
def __init__(self, name)
      self.name = name
#  (3) 每個對象存儲一份礼殊,通過對象地址調用
  • 實例方法
    實例方法表示對象的行為。同一個方法针史,操作不同的數據晶伦。
    無論創(chuàng)建多少個對象,方法都只有一份啄枕,并且被所有對象共享
類對象數據成員修改內存圖
  • 類成員
    類成員包括: 類變量 + 類方法
    重點婚陪,類變量在方法區(qū)共用,對象變量獨自開辟一個變量內存

    類變量成員內存圖

  • 語法
    定義:在類中频祝,方法外定義的變量都叫做“類變量”泌参。
    class 類名:
    變量名 = 表達式
    調用:類名.變量名
    不建議通過對象訪問類變量

  • 作用
    只存儲一份在類中,被所有對象共享常空。

  • 類方法
    定義:
    @classmethod
    def 方法名稱(cls, 參數列表)

"""
練習4: 實例變量與類變量

"""
class ICBC:
    # 定義“類變量”沽一,類共用的變量
    total_money = 1200000

    # 定義類方法
    @classmethod
    def get_total_money(cls):
        print("總行還剩余:%d 元" % cls.total_money)

    # 定義類實例構造函數
    def __init__(self, name, money):
        self.name = name  # 定義“實例變量”
        self.money = money
        ICBC.total_money -= money  # 調用“類變量”,直接用類名

    # 定義實例方法
    def print(self):
        print("%s銀行存款為:%d" % (self.name, self.money))  # 調用“實例變量”


bank01 = ICBC('曹操分行', 100000)
bank01.print()
bank02 = ICBC('劉備分行', 20000)
bank02.print()
bank03 = ICBC('孫權分行', 80000)
bank03.print()

ICBC.get_total_money()

  • 類靜態(tài)方法
    定義:
    class 類名
    @staticmethod
    def 靜態(tài)方法名
    方法體
    作用:將函數移入類中雪隧,函數既不屬于類方法儒将,又不屬于對象方法,即可以定義為類靜態(tài)方法鹦付。
class Vector:
    """
        二維向量
        可以表示位置/方向
    """

    def __init__(self, x, y):
        self.x = x
        self.y = y

    # 靜態(tài)方法:表示左邊方向
    @staticmethod
    def left():
        return Vector(0, -1)

    # 靜態(tài)方法:表示右邊方向
    @staticmethod
    def right():
        return Vector(0, 1)
封裝
  • 從數據角度講昆禽,將一些基本數據類型復合成一個自定義類型
    或者說:“將多個變量封裝到一個自定義類中”
    封裝數據():
    例如: 老婆(姓名蝗蛙,年齡,性別)
    敵人(姓名醉鳖,血量捡硅,攻擊力,防御力)
    二維向量 (x, y)
    面向方法盗棵,只能就叫“存儲數據”,例如壮韭,字典北发、列表。
    封裝數據(類)好處:可以用一個類名來表示你封裝后的產物泰涂,代碼結果清晰,事務更加明確辐怕。
    優(yōu)勢:更符合人類的思考方式逼蒙。
    將數據與對數據的操作整合在一起。

  • 從行為角度講寄疏,類向外提供必要(public)的功能是牢,隱藏(private)實現的細節(jié)。

封裝行為:例如陕截,二維列表助手類(獲取多個元素)
向量(向左驳棱,向右.....)
好處:以“模塊化”的方式進行編程(類似一個函數只做一件事情),一個大的需求农曲,需要分而治之社搅。我們可以不用理會一個“模塊”內部是怎么做的,只需要知道怎么用就可以乳规,把模塊串聯起來即可形葬。可以集中精力設計暮的、組織笙以、指揮多個類協(xié)調工作。

  • 私有成員
    做法: 命名使用雙下劃線開頭冻辩。只是一種規(guī)定猖腕,實際還是可以訪問到。
    def __私有方法
    __私有變量

重點:這里因為外層已經把 y 定義為類變量了恨闪,self.y = property 對象倘感, 9999 賦值給 property 對象
8假如沒有類變量 y (或者 類變量 y = 1000),這時 self.y 就屬于 init 方法內部變量
self.y 關鍵在于看看它本身是什么

"""
練習10:封裝練習 - 私有成員 - property
"""
class MyClass:

    def __init__(self):
        # 重點:這里因為外層已經把 y 定義為類變量了咙咽,self.y = property 對象侠仇, 9999 賦值給 property 對象
        # 假如沒有類變量 y (或者 類變量 y = 1000),這時 self.y 就屬于 __init__ 方法內部變量
        # self.y 關鍵在于看看它本身是什么
        self.y = 9999

    def get_y(self):
        return self.__y

    def set_y(self, value):
        self.__y = value

    y = property(get_y, set_y)


my01 = MyClass()
print(my01.__dict__)
property內存圖
  • 封裝 - 只讀犁珠,只寫屬性


    封裝 - 只寫屬性

    封裝 - 只讀屬性
  • property 私有屬性
    property 私有屬性可以讓對象可以像操作“公開的實例變量”一樣處理“私有屬性” (2 個方法), 即是兩個公開的屬性逻炊,保護一個私有的變量
    --@property 負責讀取,@屬性名.setter 負責寫入
    --只寫:屬性名=property(None, 寫入方法名)
  • property 私有屬性定義:
    @property
    def name(self):
    return self.__name

@name.setter
def name(self, value)
self.__name = value

  • 使用 @property 封裝私有變量
class Enemy:

    def __init__(self, name, attack, blood):
        self.name = name
        self.attack = attack
        self.blood = blood

    @property
    def attack(self, value):
        self.__attack = value

    @attack.setter
    def attack(self, value):
        if 10 <= value <= 50:
            self.__attack = value
        else:
            raise ValueError("攻擊力范圍錯誤")

    @property
    def blood(self):
        return self.__blood

    @blood.setter
    def blood(self, value):
        if 100 <= value <= 200:
            self.__blood = value
        else:
            raise ValueError("血量范圍錯誤")


enemy01 = Enemy('骷髏頭', 50, 100)
enemy01.blood = 120
print(enemy01.__dict__)
從設計角度講封裝的思想(重點)

(1)分而治之(總思想:分
---將一個大的需求分解為許多類犁享,每一個類處理一個獨立的功能余素。
---拆分的好處:便于分工,便于復用炊昆,可擴展性強桨吊。
---思想指導:活字印刷術
(2)變則疏之(對第一點補充威根,“分”的“度”,“點”在哪视乐?
---分而治之洛搀,分得有一個“度”,什么時候該拆分成一個小的分類佑淀,就看它會不會變化留美,會變化就拆分成一個小的分類。
---變化的地方獨立封裝伸刃,避免影響其他的類
---分得精髓在乎一個“變”
(3) 高內聚(審查評價評價上面兩步驟做得好嗎谎砾?)
---內聚:一個類的內部干了多少件事
---高:一個類干的事情都能凝聚到一個點,叫“高”
---高內聚:類中的各個方法都在完成一項任務(單一職責)
---高內聚:評價一個類的內部是否都只做“一件事情”
---若不是捧颅,重構景图,提出去!!!

(4)低耦合 (講的是類與類之間的關系,十有八九在說設計模式
---類與類的關聯性與依賴度要低

例如:硬件高度集成化碉哑,又要可插拔
最高的內聚莫過于類中只有1個方法挚币,將會導致高內聚高耦合。
最低的耦合莫過于類中包含所有的方法扣典,將會導致低耦合低內聚忘晤。
所有高內聚,低耦合講究一個平衡激捏。

  • slots: 限制類創(chuàng)建的對象只能有固定的類實例變量

體會: 對象區(qū)分數據的不同

"""
練習12:封裝練習 - 體會變化點是數據的不同還是行為的不同

張無忌   教    趙敏   九陽神功
趙敏     教    張無忌  化妝
張無忌   上班  掙了    10000
趙敏    上班   掙了    8000

體會: 對象區(qū)分數據的不同
"""


class Person:
    def __init__(self, name):
        self.name = name

    def teach(self, other, action):
        print("%s 教 %s %s" % (self.name, other.name, action))

    def work(self, money):
        print("%s 上班设塔,掙了 %d 元" % (self.name, money))


p1 = Person('張無忌')
p2 = Person('趙敏')
p1.teach(p2, '九陽神功')
p2.teach(p1, '化妝')
p1.work(10000)
p2.work(8000)

體會: 類區(qū)別行為的不同

"""
練習13:封裝練習 - 體會變化點是數據的不同還是行為的不同
玩家(攻擊力) 攻擊 敵人(血量), 受傷(掉血)远舅,還可能死亡(掉裝備)
敵人(攻擊力) 攻擊 玩家(血量)闰蛔, 受傷(掉血/碎屏),還可能死亡
體會: 類區(qū)別行為的不同
"""


class Player:

    def __init__(self, atk, hp):
        self.atk = atk
        self.hp = hp

    def attack(self, other):
        print("玩家攻打敵人:")
        other.damage(self.atk)

    def damage(self, atk):
        self.hp -= atk
        if self.hp <= 0:
            self.__death()

    @staticmethod
    def __death(self):
        print("玩家死亡")
        print("游戲結束")


class Enemy:

    def __init__(self, atk, hp):
        self.atk = atk
        self.hp = hp

    def damage(self, atk):
        self.hp -= atk
        print("敵人受傷了:")
        if self.hp <= 0:
            self.__die()

    @staticmethod
    def __die():
        print("敵人死亡")
        print("掉裝備")

    def attack(self, other):
        print("敵人攻打玩家:")
        other.damage(self.atk)


player = Player(100, 1000)
enemy = Enemy(10, 200)
player.attack(enemy)
enemy.attack(player)
player.attack(enemy)

?著作權歸作者所有,轉載或內容合作請聯系作者
  • 序言:七十年代末图柏,一起剝皮案震驚了整個濱河市序六,隨后出現的幾起案子,更是在濱河造成了極大的恐慌蚤吹,老刑警劉巖例诀,帶你破解...
    沈念sama閱讀 216,496評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現場離奇詭異裁着,居然都是意外死亡繁涂,警方通過查閱死者的電腦和手機,發(fā)現死者居然都...
    沈念sama閱讀 92,407評論 3 392
  • 文/潘曉璐 我一進店門二驰,熙熙樓的掌柜王于貴愁眉苦臉地迎上來扔罪,“玉大人,你說我怎么就攤上這事桶雀】蠼停” “怎么了唬复?”我有些...
    開封第一講書人閱讀 162,632評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長全肮。 經常有香客問我敞咧,道長,這世上最難降的妖魔是什么辜腺? 我笑而不...
    開封第一講書人閱讀 58,180評論 1 292
  • 正文 為了忘掉前任休建,我火速辦了婚禮,結果婚禮上哪自,老公的妹妹穿的比我還像新娘丰包。我一直安慰自己禁熏,他們只是感情好壤巷,可當我...
    茶點故事閱讀 67,198評論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著瞧毙,像睡著了一般胧华。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上宙彪,一...
    開封第一講書人閱讀 51,165評論 1 299
  • 那天矩动,我揣著相機與錄音,去河邊找鬼释漆。 笑死悲没,一個胖子當著我的面吹牛,可吹牛的內容都是我干的男图。 我是一名探鬼主播示姿,決...
    沈念sama閱讀 40,052評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼逊笆!你這毒婦竟也來了栈戳?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 38,910評論 0 274
  • 序言:老撾萬榮一對情侶失蹤难裆,失蹤者是張志新(化名)和其女友劉穎子檀,沒想到半個月后,有當地人在樹林里發(fā)現了一具尸體乃戈,經...
    沈念sama閱讀 45,324評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡褂痰,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,542評論 2 332
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現自己被綠了症虑。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片脐恩。...
    茶點故事閱讀 39,711評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖侦讨,靈堂內的尸體忽然破棺而出驶冒,到底是詐尸還是另有隱情苟翻,我是刑警寧澤,帶...
    沈念sama閱讀 35,424評論 5 343
  • 正文 年R本政府宣布骗污,位于F島的核電站崇猫,受9級特大地震影響,放射性物質發(fā)生泄漏需忿。R本人自食惡果不足惜诅炉,卻給世界環(huán)境...
    茶點故事閱讀 41,017評論 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望屋厘。 院中可真熱鬧涕烧,春花似錦、人聲如沸汗洒。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,668評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽溢谤。三九已至瞻凤,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間世杀,已是汗流浹背阀参。 一陣腳步聲響...
    開封第一講書人閱讀 32,823評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留瞻坝,地道東北人蛛壳。 一個月前我還...
    沈念sama閱讀 47,722評論 2 368
  • 正文 我出身青樓,卻偏偏與公主長得像所刀,于是被迫代替她去往敵國和親衙荐。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,611評論 2 353

推薦閱讀更多精彩內容

  • 面向對象——封裝 一勉痴、概述 Python面向對象的三大特性:封裝赫模、繼承和多態(tài)。 封裝:在類中對數據的賦值蒸矛、內部調用...
    冬日里的月光閱讀 274評論 0 0
  • Python面對對象封裝 1.1 面向過程和面向對象 根據操作數據的函數或語句塊來設計程序的過程瀑罗,叫做面向過程編程...
    Newthan閱讀 199評論 0 0
  • 封裝:將一堆零碎的東西封箱裝起來! 為什么需要封裝雏掠?封裝的作用和含義斩祭? 比如:①我要看電視,只需要按一下開關和換臺...
    云Shen不知處閱讀 299評論 3 0
  • 所謂封裝就是對外部世界隱藏對象的工作細節(jié) 今天老師講了四個例子乡话,由簡入繁摧玫,由淺入深詳細分析了封裝的意義及用法 例1...
    惡人未滿閱讀 217評論 0 0
  • 封裝演示01 前面兩種封裝方法對于數據的安全保護不夠強烈,應為對象可以直接通過objeect.name='like...
    maxlike閱讀 319評論 0 0