封裝是啥,拋開面向對象,你單去想什麼是裝,裝就是拿來一個麻袋,把小貓,小狗,小王八,還有alex一塊兒裝進麻袋,什麼是封,封就是把麻袋封上口子。
在面向對象中這個麻袋就是你的類或者對象,類或者對象這倆麻袋內部裝了數據屬性和函數屬性,那麼對於類和對象來講‘封’的概念從何而來,其實封的概念表明隱藏
第一個層面的封裝:類就是麻袋,這自己就是一種封裝
第二個層面的封裝:類中定義私有的,只在類的內部使用,外部沒法訪問
PS1:
class Game(): #約定一:任何以單下劃線開頭的名字都應該是內部的,私有的 _game_type = 'cross_f' #約定二:雙下劃線開頭的名字 __game_type = 'cross_f' #第三個層面的封裝:明確區份內外,內部的實現邏輯,外部沒法知曉,而且爲封裝到內部的邏輯提供一個訪問接口給外部使用(沒講) def __init__(self,g_name,player,gun,moeny): self.g_name = g_name self.g_player = player self.g_gun = gun self.g_moeny = moeny def buy_gun(self): print('%s買了一把%s遊戲的%s並花費了%s元'%(self.g_player,self.g_name,self.g_gun,self.g_moeny)) g1 = Game('cf','zk','blt',100) g1.buy_gun() #print(g1._game_type) #能夠訪問,這個是約定的,不是定義(你們都這麼遵照,寫_就不調用) #__的操做就解釋器就至關於作了一次賦值的操做,把__game_type————>_Game__game_typ #這兩種,都不是嚴格意義上的封裝 #print(g1.__game_type) #報錯,不能直接調用 #print(g1._Game__game_type) #可是能夠經過類,依然能夠訪問到;
總結:python
上面提到有兩種不一樣的編碼約定(單下劃線和雙下劃線 )來命名私有屬性,那麼問 題就來了:到底哪一種方式好呢?大多數而言,你應該讓你的非公共名稱以單下劃線開 頭。可是,若是你清楚你的代碼會涉及到子類,而且有些內部屬性應該在子類中隱藏 起來,那麼才考慮使用雙下劃線方案。 可是不管哪一種方案,其實python都沒有從根本上限制你的訪問。函數
若是作成私有屬性後的補救措施:編碼
不動腦子就把一個屬性作成了私有的屬性,私有屬性外部是沒法被訪問的,後來的某天你發現,這個屬性實際上是應該被放開的,因而你的解決方法是定義一個訪問函數,
在內部去調用私有屬性,的方法完美的解決了這個問題,沒錯,訪問函數確實是一種好東西,可是你這個問題的出在你濫用封裝,後來利用訪問函數去幫你填坑。
封裝在於明確區份內外,使得類實現者能夠修改封裝內的東西而不影響外部調用者;而外部調用者也能夠知道本身不能夠碰哪裏。這就提供一個良好的合做基礎——或者說,
只要接口這個基礎約定不變,則代碼改變不足爲慮。
class Room: def __init__(self,name,owner,width,length,high): self.name=name self.owner=owner self.__width=width self.__length=length self.__high=high def tell_area(self): #此時咱們想求的是面積 return self.__width * self.__length #定義一個方法,在類中可調用私有屬性,而後咱們return這個屬性 #在外部的其它函數,在調用這個類方法的時候,就能夠獲取具體類的私有屬性了,接口方法 r1=Room('衛生間','alex',100,100,10000) area=r1.tell_area() print(area)