1. 程式人生 > >面向對象——封裝

面向對象——封裝

put obj 訪問 下滑 外部 認證 如果 開頭 整型

封裝

將具體、復雜的細節封裝在一起。

1. 如何將屬性隱藏

如果想讓屬性或方法隱藏,在其前加 ‘__’ 雙下劃線,python就將其視為私有。
註意:
(1). 私有變量是在定義時生成的。
(2). python沒有實現絕對的私有,而是在定義時將私有屬性解析 ‘_類名__屬性’,(單下劃線類名雙下劃線屬性)

#其實這僅僅這是一種變形操作
#類中所有雙下劃線開頭的名稱如__x都會自動變形成:_類名__x的形式:

class A:
    __x = 1  #定義時被解釋為 _A__x

    def __init__(self, name):
        self.__name = name #
定義時被解釋為 self._A__name def __foo(self): #定義時被解釋為 _A__foo print(run foo) def bar(self): self.__foo() #只有在類內部才可以通過__foo的形式訪問到. # 外部無法通過‘類名.屬性’的方式訪問 # print(A.__x) AttributeError: type object ‘A‘ has no attribute ‘__x‘ a = A(yk) print(a.__dict__) # {‘_A__name‘: ‘yk‘}
print(_A__name) # yk 可以通過_類名__x的形式訪問

特點:
1.類中定義的__x只能在內部使用,如self.__x,引用的就是變形的結果。
2.這種變形其實正是針對外部的變形,在外部是無法通過__x這個名字訪問到的。
3.在子類定義的__x不會覆蓋在父類定義的__x,因為子類中變形成了:_子類名__x,而父類中變形成了:_父類名__x,即雙下滑線開頭的屬性在繼承給子類時,子類是無法覆蓋的。

問題:
1、這種機制也並沒有真正意義上限制我們從外部直接訪問屬性,知道了類名和屬性名就可以拼出名字:_類名__屬性,然後就可以訪問了,如a._A__N。
2、變形的過程只在類的定義是發生一次,在定義後的賦值操作,不會變形

技術分享圖片

3、在繼承中,父類如果不想讓子類覆蓋自己的方法,可以將方法定義為私有的

#正常情況
class A:
    def fa(self):
        print(from A)
    def test(self):
        self.fa()

class B(A):
    def fa(self):
        print(from B)
        
 b=B()
 b.test() # from B


#把fa定義成私有的,即__fa
class A:
    def __fa(self): #在定義時就變形為_A__fa
        print(from A)
    def test(self):
        self.__fa() #只會與自己所在的類為準,即調用self._A__fa

class B(A):
    def __fa(self):
        print(from B)

b=B()
b.test() # from A

2. 封裝不是單純意義的隱藏

# 1:封裝數據。將數據隱藏起來這不是目的。
# 隱藏起來然後對外提供操作該數據的接口,然後我們可以在接口附加上對該數據操作的限制,
# 以此完成對數據屬性操作的嚴格控制。

class People:
    def __init__(self,name,age):
        self.__name = name
        self.__age = age
        
    # 訪問接口
    def tell_info(self):
        print(姓名:%s,年齡:%s % (self.__name, self.__age))
        
    # 修改接口
    def set_info(self, name, age):
        # 添加自己的控制邏輯
        if not isinstance(name, str):
            raise TypeError(姓名必須是字符串類型)
        if not isinstance(age, int):
            raise TypeError(年齡必須是整型)
        self.__name = name
        self.__age = age
        
p = People(yk,18)
p.tell_info() # yk,年齡:18
p.set_info(小明,15)
p.tell_info() # 小明,年齡:15
p.set_info(小花,14) # 報錯 TypeError: 年齡必須是整型
# 2:封裝方法,隔離復雜度
#取款是功能,而這個功能有很多功能組成:插卡、密碼認證、輸入金額、打印賬單、取錢
#對使用者來說,只需要知道取款這個功能即可,其余功能我們都可以隱藏起來,很明顯這麽做
#隔離了復雜度,同時也提升了安全性.

class ATM:
    def __card(self):
        print(插卡)
    def __auth(self):
        print(用戶認證)
    def __input(self):
        print(輸入取款金額)
    def __print_bill(self):
        print(打印賬單)
    def __take_money(self):
        print(取款)

    def withdraw(self):
        self.__card()
        self.__auth()
        self.__input()
        self.__print_bill()
        self.__take_money()

a=ATM()
a.withdraw()

面向對象——封裝