一、什么是封裝
在程序設(shè)計中,封裝(Encapsulation)是對具體對象的一種抽象,即將某些部分隱藏起來,在程序外部看不到,其
含義是其他程序無法調(diào)用。
要了解封裝,離不開“私有化”,就是將類或者是函數(shù)中的某些屬性限制在某個區(qū)域之內(nèi),外部無法調(diào)用。
二、為什么要封裝
封裝數(shù)據(jù)的主要原因是:保護隱私(把不想別人知道的東西封裝起來)
封裝方法的主要原因是:隔離復雜度(比如:電視機,我們看見的就是一個黑匣子,其實里面有很多電器元件,對于
用戶來說,我們不需要清楚里面都有些元件,電視機把那些電器元件封裝在黑匣子里,提供給用戶的只是幾個按鈕接口,
通過按鈕就能實現(xiàn)對電視機的操作。)
提示:在編程語言里,對外提供的接口(接口可理解為了一個入口),就是函數(shù),稱為接口函數(shù),這與接口的概念還
不一樣,接口代表一組接口函數(shù)的集合體。
三、封裝分為兩個層面
封裝其實分為兩個層面,但無論哪種層面的封裝,都要對外界提供好訪問你內(nèi)部隱藏內(nèi)容的接口(接口可以理解為入
口,有了這個入口,使用者無需且不能夠直接訪問到內(nèi)部隱藏的細節(jié),只能走接口,并且我們可以在接口的實現(xiàn)上附加更
多的處理邏輯,從而嚴格控制使用者的訪問)
第一個層面的封裝(什么都不用做):創(chuàng)建類和對象會分別創(chuàng)建二者的名稱空間,我們只能用類名.或者obj.的方式去
訪問里面的名字,這本身就是一種封裝。
print(m1.brand)#實例化對象(m1.)
print(motor_vehicle.tag)#類名(motor_vehicle.)
-------------輸出結(jié)果--------------
春風
fueloil
注意:對于這一層面的封裝(隱藏),類名.和實例名.就是訪問隱藏屬性的接口
第二個層面的封裝:類中把某些屬性和方法隱藏起來(或者說定義成私有的),只在類的內(nèi)部使用、外部無法訪問,或
者留下少量接口(函數(shù))供外部訪問。
Python中私有化的方法也比較簡單,即在準備私有化的屬性(包括方法、數(shù)據(jù))名字前面加兩個下劃線即可。
類中所有雙下劃線開頭的名稱如__x都會自動變形成:_類名__x的形式:
classA:
__N=0#類的數(shù)據(jù)屬性就應(yīng)該是共享的,但是語法上是可以把類的數(shù)據(jù)屬性設(shè)置成私有的如__N,會變形為_A__N
def__init__(self):
self.__X=10#變形為self._A__X
def__foo(self):#變形為_A__foo
print('fromA')
defbar(self):
self.__foo()#只有在類內(nèi)部才可以通過__foo的形式訪問到.
這種自動變形的特點:
1、類中定義的__x只能在內(nèi)部使用,如self.__x,引用的就是變形的結(jié)果。
2、這種變形其實正是針對外部的變形,在外部是無法通過__x這個名字訪問到的。
3、在子類定義的__x不會覆蓋在父類定義的__x,因為子類中變形成了:_子類名__x,而父類中變形成了:_父
類名__x,即雙下滑線開頭的屬性在繼承給子類時,子類是無法覆蓋的。
注意:對于這一層面的封裝(隱藏),我們需要在類中定義一個函數(shù)(接口函數(shù))在它內(nèi)部訪問被隱藏的屬性,然后
外部就可以使用了
這種變形需要注意的問題是:
1、這種機制也并沒有真正意義上限制我們從外部直接訪問屬性,知道了類名和屬性名就可以拼出名字:_類名__屬
性,然后就可以訪問了,如a._A__N
a=A()
print(a._A__N)
print(a._A__X)
print(A._A__N)
--------輸出結(jié)果--------
0
10
0
2、變形的過程只在類的定義是發(fā)生一次,在定義后的賦值操作,不會變形
a=A()#實例化對象a
print(a.__dict__)#打印變形的內(nèi)容
a.__Y=20#新增Y的值,此時加__不會變形
print(a.__dict__)#打印變形的內(nèi)容
---------輸出結(jié)果----------
{'_A__X':10}
{'_A__X':10,'__Y':20}#發(fā)現(xiàn)后面的Y并沒有變形
3、在繼承中,父類如果不想讓子類覆蓋自己的方法,可以將方法定義為私有的
classA:#這是正常情況
deffa(self):
print("fromA")
deftest(self):
self.fa()
classB(A):
deffa(self):
print("fromB")
b=B()
b.test()
--------輸出結(jié)果----------
fromB
看一下把fa被定義成私有的情況:
classA:#把fa定義成私有的,即__fa
def__fa(self):#在定義時就變形為_A__fa
print("fromA")
deftest(self):
self.__fa()#只會與自己所在的類為準,即調(diào)用_A__fa
classB(A):
def__fa(self):#b調(diào)用的是test,跟這個沒關(guān)系
print("fromB")
b=B()
b.test()
-------輸出結(jié)果---------
fromA
以上內(nèi)容為大家介紹了Python基礎(chǔ)之封裝,希望對大家有所幫助,如果想要了解更多Python相關(guān)知識,請關(guān)注IT培訓機構(gòu):千鋒教育。