面向对象编程:封装特性详解
什么是封装?
封装是面向对象编程的三大核心特性之一。简单来说,就是将数据(属性)和操作数据的方法(行为)捆绑在一个独立的单元(即“类”)中。
封装的核心思想是“隐藏实现细节,暴露访问接口”。它就像一台自动取款机,你只需要知道如何使用存款、取款按钮(公共接口),而无需了解机器内部复杂的电路和机械结构(私有实现)。
封装的主要目的:
- 数据安全: 通过限制对内部数据的直接访问,防止数据被意外或恶意修改,保证数据的完整性和一致性。
- 降低复杂性: 隐藏了复杂的内部逻辑,使用者只需关心“做什么”,而无需了解“怎么做”,简化了调用方式。
- 提高可维护性: 只要公共接口不变,内部的实现逻辑可以自由修改,而不会影响到外部的调用代码。
知识体系思维导图
面向对象三大特性
├── 封装
│ ├── 核心思想
│ │ ├── 捆绑数据与方法
│ │ └── 隐藏实现细节
│ ├── 实现方式
│ │ ├── 私有属性 ( __属性名 )
│ │ └── 私有方法 ( __方法名 )
│ ├── 访问控制
│ │ ├── 私有成员:类内部可访问
│ │ └── 公共接口:类外部访问的唯一途径
│ └── 主要优点
│ ├── 数据安全
│ ├── 降低复杂性
│ └── 提高可维护性
├── 继承
└── 多态
封装的实现
在 Python 中,封装主要通过将属性和方法定义为“私有”来实现。
私有属性
- 定义方式: 在属性名前加上双下划线
__,例如self.__age。 - 访问限制: 私有属性无法在类的外部被直接访问。
- 访问方式: 通常通过定义公共的
getter和setter方法来获取和修改私有属性的值。在这些方法中,可以加入权限校验、数据验证等逻辑。
私有方法
- 定义方式: 在方法名前加上双下划线
__,例如def __helper(self):。 - 访问限制: 私有方法无法在类的外部被直接调用。
- 作用: 用于封装复杂的内部操作细节,让公共方法看起来更简洁,降低程序的复杂性。
代码示例
示例1:私有属性的封装
这个例子展示了如何通过公共方法来安全地访问和修改私有属性 __age。
class Person(object):
def __init__(self, name, age):
self.name = name
self.__age = age # 私有属性
self._height = 180 # 受保护的属性(约定俗成,不强制)
# 公开获取私有属性的方法 (getter)
def get_age(self):
# 可以在这里加入权限校验逻辑
if self.name == '张三':
return f"获取私有属性 age 的值: {self.__age}"
return "无权限访问"
# 公开设置私有属性的方法 (setter)
def set_prop(self, name, age):
print(f"设置私有属性 age 的值: {age}")
# 加入数据验证逻辑
if isinstance(name, str):
self.name = name
if isinstance(age, int) and 0 <= age <= 120:
self.__age = age
# 创建对象
p1 = Person('张三', 18)
print(p1.name) # 输出: 张三
print(p1.get_age()) # 输出: 获取私有属性 age 的值: 18
p1.set_prop('李四', 20) # 设置新值
print(p1.get_age()) # 输出: 无权限访问 (因为名字已改为李四)
示例2:私有方法的封装
这个例子展示了如何使用私有方法来隐藏复杂的内部步骤,只暴露一个简单的公共接口。
class ATM(object):
# 私有方法:内部操作细节
def __card(self):
print("插入银行卡")
def __authorization(self):
print("输入密码认证用户")
def __view_balance(self):
print("查看余额")
def __get_money(self):
print("取钱")
# 公开方法:对外提供的简单接口
def withdraw(self):
self.__card()
self.__authorization()
self.__view_balance()
self.__get_money()
# 使用
wd = ATM()
wd.withdraw() # 只需调用一个方法,即可完成一系列复杂操作
综合练习:银行账户类
这个练习结合了私有属性和私有方法,实现了一个简单的银行账户类。
class BankAccount(object):
# 初始化属性
def __init__(self, username, balance):
self.username = username
self.__balance = balance # 私有属性:余额
# 私有方法:验证金额是否合法
def __valid_amount(self, amount):
if isinstance(amount, int) and 0 < amount <= 5000:
return True
print("金额不合法,请输入大于0且不超过5000的整数金额。")
return False
# 存钱方法
def save_money(self, amount):
if self.__valid_amount(amount):
self.__balance += amount
print("存款成功!")
print(self)
# 取钱方法
def get_money(self, amount):
if self.__valid_amount(amount):
if self.__balance >= amount:
self.__balance -= amount
print("取款成功!")
else:
print("余额不足!")
print(self)
# 定义对象的字符串表示
def __str__(self):
return f"用户名:{self.username}, 余额:{self.__balance}"
# 使用示例
bank_account = BankAccount('张三', 1000)
bank_account.save_money(500) # 存款500
bank_account.save_money(2000) # 尝试存款2000 (超过限额)
bank_account.get_money(4000) # 尝试取款4000 (余额不足)