封装是面向对象编程(OOP)的基本概念之一。它描述了包装数据的思想以及在一个单元内处理数据的方法。这对直接访问变量和方法施加了限制,并且可以防止数据的意外修改。为了防止意外更改,对象的变量只能通过对象的方法进行更改。这些类型的变量称为私有变量。
类是封装的一个示例,因为它封装了成员函数、变量等所有数据。信息隐藏的目标是通过控制对外界隐藏的属性的访问来确保对象的状态始终有效。
考虑一个现实生活中的封装示例,在公司中,有不同的部门,例如会计部门、财务部门、销售部门等。财务部门处理所有财务交易并保存与财务相关的所有数据的记录。同样,销售部门处理所有与销售相关的活动并保存所有销售的记录。现在可能会出现这样的情况:由于某种原因,财务部门的负责人需要特定月份的所有销售数据。在这种情况下,他不可以直接访问销售部分的数据。他首先必须联系销售部门的负责人,然后要求他提供特定数据。这就是封装。这里,销售部门的数据以及可以操纵它们的员工被包装在一个名称“销售部门”下。使用封装还可以隐藏数据。在此示例中,销售、财务或帐户等部分的数据对任何其他部分都隐藏。
受保护会员
受保护成员(在 C++ 和 JAVA 中)是类中不能在类外部访问但可以从类及其子类内部访问的成员。要在 Python 中完成此操作,只需遵循约定,在成员名称前添加一个下划线“_”。
尽管受保护的变量可以在类外以及派生类中访问(也在派生类中进行修改),但习惯上(约定而不是规则)不从类主体中访问受保护的变量。
注意: __init__ 方法是一个构造函数,在实例化类的对象后立即运行。
# Python程序演示受保护的成员
# 创建一个基类
class Base:
def __init__(self):
# 受保护的成员
self._a = 2
# 创建一个派生类
class Derived(Base):
def __init__(self):
# 调用基类的构造函数
Base.__init__(self)
print("调用基类的受保护成员:",
self._a)
# 修改受保护的变量:
self._a = 3
print("在类外部调用修改后的受保护成员:",
self._a)
obj1 = Derived()
obj2 = Base()
# 调用受保护的成员
# 可以访问,但根据约定不应该这样做
print("访问obj1的受保护成员:", obj1._a)
# 在外部访问受保护的变量
print("访问obj2的受保护成员:", obj2._a)
输出:
调用基类的受保护成员: 2
在类外部调用修改后的受保护成员: 3
访问obj1的受保护成员: 3
访问obj2的受保护成员: 2
私有成员
私有成员与受保护成员类似,不同之处在于声明为私有的类成员既不能被类外部访问,也不能被任何基类访问。在Python中,不存在除类内部之外无法访问的私有实例变量。
但是,要定义私有成员,请在成员名称前添加双下划线“__”。
注意: Python 的私有和受保护成员可以通过python name mangling在类外部访问。
# Python程序演示私有成员
# 创建一个基类
class Base:
def __init__(self):
self.a = "JkhxwforGeeks"
self.__c = "JkhxwforGeeks"
# 创建一个派生类
class Derived(Base):
def __init__(self):
# 调用基类的构造函数
Base.__init__(self)
print("调用基类的私有成员: ")
print(self.__c)
# 主程序
obj1 = Base()
print(obj1.a)
# 取消注释print(obj1.c)将会
# 引发AttributeError错误
# 取消注释obj2 = Derived()也会
# 引发AttributeError错误,因为
# 在派生类中调用了基类的私有成员
输出:
JkhxwforGeeks
Traceback (most recent call last):
File "/home/f4905b43bfcf29567e360c709d3c52bd.py", line 25, in <module>
print(obj1.c)
AttributeError: 'Base' object has no attribute 'c'
Traceback (most recent call last):
File "/home/4d97a4efe3ea68e55f48f1e7c7ed39cf.py", line 27, in <module>
obj2 = Derived()
File "/home/4d97a4efe3ea68e55f48f1e7c7ed39cf.py", line 20, in __init__
print(self.__c)
AttributeError: 'Derived' object has no attribute '_Derived__c'
原创文章,作者:jkhxw,如若转载,请注明出处:https://www.jkhxw.com/python-encapsulation/