三大特性:封装 封装

封装是啥,抛开面向对象,你单去想什么是装,装就是拿来一个麻袋,把小猫,小狗,小王八,还有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)