Files
PythonLearn/03_面向对象/3_2_Python与Java的封装差异/practice.py

71 lines
3.3 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 第 3-2 课课堂练习Python 与 Java 的封装差异
#
# 关键规则已经写进每部分题目,可以不先完整阅读讲义。
# 请保留题目、预期结果和自查说明,并独立完成 Product 类。
# 第一部分:定义 Product 类和初始化方法
# 1. 定义 __init__(self, name, price) 方法。
# 2. name 标注为 strprice 标注为 float返回值标注可自行决定是否添加。
# 3. 使用 self._name = name 保存名称。
# 4. 使用 self.__price = 0.0 建立双下划线属性。
# 5. 最后执行 self.price = price通过后面定义的 setter 完成初始价格校验。
#
# Java 对照提醒:
# - _name 只表示“内部使用”的约定,外部访问不会产生语法错误;
# - __price 会触发名称改写,但不等于 Java 的强制 private
# - 双下划线不能作为保存密码等敏感信息的安全措施。
# 第二部分:为 name 定义只读 property
# 1. 在方法上方添加 @property。
# 2. 定义 name(self) 方法并返回 self._name。
# 3. 不要定义 @name.setter使调用者不能通过 product.name = ... 正常修改名称。
#
# Java 对照提醒:
# - Java 常写 getName()Python 调用时直接写 product.name
# - 虽然调用形式像字段,但实际上会执行 name() 方法。
# 第三部分:为 price 定义可读写 property
# 1. 使用 @property 定义 price(self),返回 self.__price。
# 2. 使用 @price.setter 定义同名方法 price(self, value)。
# 3. value 标注为 float。
# 4. value 小于 0 时执行 raise ValueError("价格不能小于 0。")。
# 5. 校验通过后执行 self.__price = value。
#
# Java 对照提醒:
# - 这相当于 getPrice() 和 setPrice(),但调用形式仍是 product.price
# - 不要同时保留公开的 price 实例属性,否则会和 property 的职责混淆。
# 第四部分:定义 discount(self, rate) 实例方法
# 1. rate 标注为 float。
# 2. rate 必须满足 0 <= rate <= 1否则抛出 ValueError("折扣率必须在 0 到 1 之间。")。
# 3. 合法时执行 self.price = self.price * rate。
# 4. 通过 property 修改价格,复用统一的价格入口。
# 第五部分:定义 main() 并验证行为
# 1. 创建 Product("机械键盘", 500.0)。
# 2. 输出“商品机械键盘价格500.0 元”。
# 3. 执行 product.price = 450.0再输出“修改后价格450.0 元”。
# 4. 执行 product.discount(0.8)再输出“折扣后价格360.0 元”。
# 5. 使用 try...except 测试 product.price = -1.0。
# 6. 捕获 ValueError 后输出“非法价格已被阻止:价格不能小于 0。”。
# 7. 添加程序入口判断并调用 main()。
#
# 预期输出:
# 商品机械键盘价格500.0 元
# 修改后价格450.0 元
# 折扣后价格360.0 元
# 非法价格已被阻止:价格不能小于 0。
# 完成后自查:
# 1. 是否知道单下划线只是内部使用约定;
# 2. 是否知道双下划线会名称改写,但不是绝对私有;
# 3. 是否能用 @property 代替简单的 Java getter
# 4. 是否能用 @属性名.setter 在赋值时执行校验;
# 5. 是否能说明 product.price 看似访问字段、实际会执行方法;
# 6. 是否只把运行错误和逻辑错误视为阻塞项,不把可选类型注解当作必须项。