封装之如何隐藏对象及封装的意义
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()
以上是关于封装之如何隐藏对象及封装的意义的主要内容,如果未能解决你的问题,请参考以下文章