面向对象高级-封装
面向对象高级-封装
封装的含义、类属性与实例属性、私有属性与私有方法的定义(__ 前缀)以及 Python 的"伪私有"机制
封装是什么
封装就是把数据(属性)和操作数据的函数(方法)捆绑在一起,形成一个独立的单元(类),并隐藏内部的实现细节,只对外暴露必要的功能(方法)。
一句话:该让别人看的露出来,不该看的藏起来。
类属性与实例属性
class Car: # 类属性:所有实例对象共享的 wheel = 4 # 轮胎数量 tax_rate = 0.1 # 购置税税率
def __init__(self, c_color, c_brand, c_name): # 实例属性:每个对象各自一份 self.color = c_color self.brand = c_brand self.name = c_name
def start(self): print(f'{self.brand} {self.name} 正在启动...')
def stop(self): print(f'{self.brand} {self.name} 停止行驶...')| 类型 | 写在哪 | 特点 |
|---|---|---|
| 类属性 | 类体里、方法外 | 所有实例共享(如 wheel = 4) |
| 实例属性 | __init__ 里用 self.xxx | 每个对象各有一份(如 self.color) |
私有属性与私有方法
class Car: def __init__(self, c_color, c_brand, c_name, c_owner): self.color = c_color self.brand = c_brand self.name = c_name self.__owner = c_owner # 私有属性:名字前加 __
def start(self): print(f'{self.brand} {self.name} 正在启动...')
def run(self): print(f'{self.__owner} : {self.brand} {self.name} 正在行驶...') self.__control_fuel() # 类的内部可以调用私有方法
def __control_fuel(self): # 私有方法:名字前加 __ print(f'{self.brand} {self.name} 正在控制燃油分配...')
def get_owner(self): # 对外暴露一个"脱敏"的读取方式 return self.__owner[0:1] + "**"| 公共属性/方法 | 私有属性/方法 | |
|---|---|---|
| 定义方式 | 直接写名字 | 名字前加 两个下划线 __ |
| 类的内部 | 可以访问 | 可以访问 |
| 类的外部 | 可以访问 | 不能访问 |
| 应用场景 | 对外功能 | 不想对使用者公开的内部实现 |
Python 中并没有真正的私有机制,只是”约定”:名字前加 __ 的属性会被改名成 _类名__属性名,所以在外面写 car._Car__owner 依然能访问到——但不要这么干,那等于绕过约定。
私有属性不是”藏起来就完事”,而是要提供安全的对外接口。比如例子里的 get_owner() 返回脱敏后的名字(涛哥 → 涛**),既满足了外部需求,又不泄露完整信息。
相关
练习题
一、回忆填空(写完再展开对答案)
- 封装就是把 ____ 和操作数据的 ____ 捆绑在一起,形成独立的类,并隐藏内部实现细节
- 所有实例共享的属性叫 ____ 属性(写在类体里、方法外);每个对象各有一份的叫 ____ 属性(写在 ____ 方法里)
- 私有属性/方法的名字前要加 ____;它们只能在类的 ____ 使用
- Python ____(有/没有)真正的私有机制,它只是一种 ____
- 私有属性被改名后的形式是
____类名__属性名 - 想让外部安全地读取私有属性,正确做法是提供 ____
填空答案(做完再点开)
- 数据(属性)/ 函数(方法) 2. 类 / 实例 /
__init__3. 两个下划线__/ 内部 4. 没有 / 约定 5._6. 对外暴露的公共方法(如get_owner())
二、裸写题
-
2-1 写一个带私有属性的类 定义
BankAccount类:私有属性__balance(余额),提供deposit(金额)存钱、get_balance()查余额两个公共方法。提示(先自己想,实在想不出再点开)一级 · 思路:余额设为私有,只通过方法修改和读取 二级 · 方法:
self.__balance在__init__里初始化 三级 · 骨架:def deposit(self, amount): self.__balance += amount -
2-2 验证”私有”并不真私有 在类外面分别尝试访问
__balance和_类名__balance,观察两者的结果并解释原因。提示一级 · 思路:直接用点号访问私有属性会报错,但加上类名前缀就”绕”过去了 二级 · 方法:
account.__balance(报 AttributeError)/account._BankAccount__balance三级 · 骨架:用try/except捕获 AttributeError 打印提示 -
2-3 提供脱敏接口 给
BankAccount加一个方法,返回脱敏后的账户信息(比如卡号只留后 4 位)。提示一级 · 思路:私有属性做到”内部完整、对外脱敏” 二级 · 方法:字符串切片
card[-4:]三级 · 骨架:return "****" + self.__card[-4:]
参考答案(做完再点开)
class BankAccount: def __init__(self, card, balance): self.__card = card # 私有:卡号 self.__balance = balance # 私有:余额
def deposit(self, amount): if amount <= 0: print("存款金额必须大于 0") return self.__balance += amount print(f"存款成功,当前余额:{self.__balance}")
def get_balance(self): return self.__balance
def get_card_info(self): # 脱敏接口 return "****" + self.__card[-4:]
account = BankAccount("6222021234567890", 100)account.deposit(50)print(account.get_balance()) # 150print(account.get_card_info()) # ****7890
# 2-2:私有并不真私有try: print(account.__balance)except AttributeError as e: print("直接访问私有属性失败:", e) # 报错print(account._BankAccount__balance) # 150(能"绕"进去,但不建议这么做)评论区
如果你喜欢,那么欢迎来到我的世界!
了解更多













