[Python3]封装的特性

封装

面向对象三大特性:继承,多态,封装

如何实现属性的隐藏

在python中用双下划线开头的方式将属性隐藏起来(设置成私有的)
其实这是一种变形操作
类中所有双下划线开头的名称如__x都会自动变形成:_类名__x的形式。

这种变形的特点:

在类定义阶段就发生了变形
    1. 在类外部无法直接使用 obj.__AttrName
    2. 在类内部可以直接使用 obj.__AttrName
    3. 子类无法覆盖父类__开头的属性(在类的定义阶段就发生了变形,子类和父类的看起来的同名函数就已经发生了变形:_子类名__函数名/_父类名__函数名)

例1
class A:
    __x = 1         # _A__x = 1

    def __init__(self,name):
        self.__name = name      # self._A__name = 'wyq'

    def __foo(self):            # _A__foo
        print('run foo')

    def bar(self):
        self.__foo()
        print('from bar')

print(A.__dict__)
a = A('wyq')
a.bar()

例2
class Foo:
    def __func(self):   # _Foo__func
        print('from foo')

class Bar(Foo):
    def __func(self):   # _Bar__func
        print('from bar')

b = Bar()


总结这种变形需要注意的问题:

 1.这种机制也并没有真正意义上的限制我们从外部直接访问属性,知道了类名和属性名就可以拼出名字:_类名__属性,然后就可以访问了。
 2.变形的过程只在类的定义时发生一次,在定义后的赋值操作,不会变形
 3.在继承中,父类如果不想让子类覆盖自己的方法,可以将方法定义为私有的

class B:
    __x = 1
    def __init__(self, name):
        self.__name = name

# 验证问题一
print(B._B__x)

# 验证问题二
B.__y = 2
print(B.__dict__)   # {....... ,'__y': 2}
b = B('wyq')
print(b.__dict__)

# 验证问题三
class A:
    def __foo(self):
        print('A.foo')
    def bar(self):
        print('A.bar')
        self.__foo()

class B(A):
    def __foo(self):
        print('B.foo')

b = B()
b.bar()
 

猜你喜欢

转载自blog.csdn.net/TynMhxx/article/details/81807306