封装之如何隐藏对象及封装的意义

Posted huizaia

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了封装之如何隐藏对象及封装的意义相关的知识,希望对你有一定的参考价值。

python中通常在属性和方法前加__(两条下划线)来进行属性和方法的隐藏。

特点:

1.在类外无法直接obj.__AttrName

2.在类内部可以直接使用obj.__AttrName

3.子类无法覆盖父类__开头的属性

 

1.在类外无法直接obj.__AttrName

class A:
    def __init__(self, name, life):
        self.__name = name
        self.__life = life

    def __run(self):
        print(run)

    def sing(self):
        self.__run()
        print(sing)

b = A(gaohui, 100)
print(b.__name)


报错:
AttributeError: A object has no attribute __name

 

2.在类内部可以直接使用obj.__AttrName

class A:
    def __init__(self, name, life):
        self.__name = name
        self.__life = life

    def __run(self):
        print(run)

    def sing(self):
        self.__run()
        print(sing)

b = A(gaohui, 100)
b.sing()

输出结果:
run
sing

此时的__run正常输出了,因为在类的定义时,self.__run()已经便成了self._A__run()

 

3.子类无法覆盖父类__开头的属性

class A:
    def __init__(self, name, life):
        self.__name = name
        self.__life = life

    def __run(self):
        print(run)

    def sing(self):
        self.__run()
        print(sing)

class B(A):
    def __init__(self, name, age, life):
        super().__init__(name, age)
        self.__life = life

    def __run(self):
        print(---)
        

print(A.__dict__)
print(B.__dict__)


输出结果:
{__module__: __main__, __init__: <function A.__init__ at 0x1068190d0>, _A__run: <function A.__run at 0x1068192f0>,
{__module__: __main__, __init__: <function B.__init__ at 0x106819730>, _B__run: <function B.__run at 0x1068197b8>,

两个run方法的属性是不一样的。

 

方法和属性隐藏需要注意的地方:

1.外部不能直接饮用,需要对象._类__属性的形式可以提出隐藏的属性和方法

2.变形的过程只有在类的定义时发生一次,再次赋值时不会变形。

3.在继承中,如果父类不想让子类覆盖自己的方法,可以将方法定义为私有的。

 

1.外部不能直接饮用,需要对象._类__属性的形式可以提出隐藏的属性和方法

class A:
    def __init__(self, name, life):
        self.__name = name
        self.__life = life

    def __run(self):
        print(run)

    def sing(self):
        self.__run()
        print(sing)

a = A(gaohui, 100)
print(a._A__name)


输出结果:
gaohui

 

2.变形的过程只有在类的定义时发生一次,再次赋值时不会变形。

class A:
    def __init__(self, name, life):
        self.__name = name
        self.__life = life

    def __run(self):
        print(run)

    def sing(self):
        self.__run()
        print(sing)

A.__b = 1
a = A(gaohui, 100)
print(a._A__name)
print(A.__b)


输出结果:
gaohui
1

当类已经定义好了,再次定义时不会变形成隐藏的模式。

 

3.在继承中,如果父类不想让子类覆盖自己的方法,可以将方法定义为私有的。

class A:
    def __fa(self):     *_A__fa
        print(from A)

    def test(self):
        self.__fa()  # 此时的fa方法是变形过的_A__fa,所以之行类A中的fa方法


class B(A):
    def __fa(self):    *_B__fa
        print(from B)


b = B()
b.test()


输出结果:

from A

 

封装数据属性的意义:明确的区分内外,控制外部对隐藏的属性的操作行为

class A:
    def __init__(self, name, age):
        self.__name = name
        self.__age = age

    def tell_info(self):        # 可以通过一个接口来显示被隐藏的数据,不能直接被外部调用
        print(name is %s, age is %s % (self.__name, self.__age))

    def search_info(self, name, age):
        if not isinstance(name, str):  # 检验是不是字符串
            print(姓名为字符串)
            return
        if not isinstance(age, int):
            print(年龄已经为整数)
            return
        self.__name = name
        self.__age = age
        self.tell_info()


st = A(GAO, 23)
print(st.__dict__)
#st.search_info(‘Gww‘, 23)  # 可以通过一个接口来修改name和age,而不是直接修改

 

封装方法:

class ATM:
    def __card(self):
        print(插卡)

    def __auth(self):
        print(用户验证)

    def __input(self):
        print(输入取款金额)

    def withdraw(self):
        self.__card()
        self.__auth()
        self.__input()


a = ATM()
a.withdraw()

 

以上是关于封装之如何隐藏对象及封装的意义的主要内容,如果未能解决你的问题,请参考以下文章

面向对象之封装

面向对象之封装

python面向对象三大特性之封装

Java中面向对象的三大特性之封装

面向对象特征之封装性

面向对象之封装 及@property装饰器使用