三大特性:封装
封装
封装是啥,抛开面向对象,你单去想什么是装,装就是拿来一个麻袋,把小猫,小狗,小王八,还有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都没有从根本上限制你的访问。
如果做成私有属性后的补救措施:
不动脑子就把一个属性做成了私有的属性,私有属性外部是无法被访问的,后来的某天你发现,这个属性其实是应该被放开的,于是你的解决方法是定义一个访问函数,
在内部去调用私有属性,的方法完美的解决了这个问题,没错,访问函数确实是一种好东西,但是你这个问题的出在你滥用封装,后来利用访问函数去帮你填坑。
封装在于明确区分内外,使得类实现者可以修改封装内的东西而不影响外部调用者;而外部调用者也可以知道自己不可以碰哪里。这就提供一个良好的合作基础——或者说,
只要接口这个基础约定不变,则代码改变不足为虑。
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)