一、封装(Encapsulation)

核心思想:把数据(属性)和操作(方法)包装在一个类里,并通过访问控制(公有、私有)保护内部细节,只暴露必要的接口。

作用

  • 开放有限的功能和信息:隐藏内部实现细节,外部只能通过规定的方法访问或修改数据。

  • 仅限内部访问的信息和内部员工使用的工具,不对外开放:提高安全性、可维护性,防止外部随意篡改对象状态。——机密信息放在私有属性中,不允许外部访问;

class BankAccount:
    def __init__(self, owner, balance):
        self.owner = owner          # 公有属性
        self.__balance = balance    # 私有属性(双下划线开头)

    def deposit(self, amount):
        if amount > 0:
            self.__balance += amount
            print(f"存款 {amount} 元成功,当前余额:{self.__balance}")
        else:
            print("存款金额必须大于 0")

    def withdraw(self, amount):
        if 0 < amount <= self.__balance:
            self.__balance -= amount
            print(f"取款 {amount} 元成功,当前余额:{self.__balance}")
        else:
            print("余额不足或金额无效")

    def get_balance(self):         # 提供公有方法访问私有属性
        return self.__balance


# 使用
acc = BankAccount("张三", 1000)
print(acc.owner)               # 正常访问公有属性
# print(acc.__balance)         # 报错,不能直接访问私有属性
print(acc.get_balance())       # 通过方法获取余额
acc.deposit(500)               # 调用公有方法修改内部状态

二、继承(Inheritance)

核心思想:子类可以继承父类的属性和方法,避免重复代码,并可以在子类中扩展或重写功能。

作用

  • 代码复用:公共属性和方法写在父类,子类直接使用。

  • 扩展功能:子类可以增加新方法或重写父类方法。

# 父类
class Animal:
    def __init__(self, name):
        self.name = name

    def speak(self):
        raise NotImplementedError("子类必须实现 speak 方法")


# 子类
class Dog(Animal):
    def speak(self):
        return f"{self.name} 汪汪叫"


class Cat(Animal):
    def speak(self):
        return f"{self.name} 喵喵叫"


# 使用
dog = Dog("旺财")
cat = Cat("咪咪")
print(dog.speak())   # 旺财 汪汪叫
print(cat.speak())   # 咪咪 喵喵叫

三、多态

多态的核心是:不同类的对象调用相同的方法名,表现出不同的行为

在银行场景中,“计息”就是一个典型的多态场景:不同类型的账户(活期、定期、信用卡)计息规则完全不同,但我们可以用统一的接口来计算利息。

多态示例:不同类型账户的计息

1. 基类(统一接口)

class Account:
    def __init__(self, owner, balance):
        self.owner = owner
        self.balance = balance

    def calculate_interest(self):
        """基类只定义接口,不实现具体逻辑"""
        raise NotImplementedError("子类必须实现 calculate_interest 方法")

好的,我再给你一个更贴近银行业务的多态例子,帮助你加深理解。

多态的核心是:不同类的对象调用相同的方法名,表现出不同的行为

在银行场景中,“计息”就是一个典型的多态场景:不同类型的账户(活期、定期、信用卡)计息规则完全不同,但我们可以用统一的接口来计算利息。


多态示例:不同类型账户的计息

1. 基类(统一接口)

class Account:
    def __init__(self, owner, balance):
        self.owner = owner
        self.balance = balance

    def calculate_interest(self):
        """基类只定义接口,不实现具体逻辑"""
        raise NotImplementedError("子类必须实现 calculate_interest 方法")

2. 子类(不同实现)

class SavingsAccount(Account):
    """活期账户:年利率 0.35%,按日计息"""
    def __init__(self, owner, balance):
        super().__init__(owner, balance)
        self.interest_rate = 0.0035 / 365  # 日利率

    def calculate_interest(self):
        interest = self.balance * self.interest_rate
        return round(interest, 2)


class FixedDepositAccount(Account):
    """定期账户:年利率 2.5%,按整年计息"""
    def __init__(self, owner, balance, years):
        super().__init__(owner, balance)
        self.years = years
        self.interest_rate = 0.025  # 年利率

    def calculate_interest(self):
        interest = self.balance * self.interest_rate * self.years
        return round(interest, 2)


class CreditCardAccount(Account):
    """信用卡账户:不计存款利息,反而可能有循环利息"""
    def __init__(self, owner, balance):
        super().__init__(owner, balance)

    def calculate_interest(self):
        # 假设余额为负(欠款),按日利率 0.05% 计息
        if self.balance < 0:
            daily_rate = 0.0005
            interest = abs(self.balance) * daily_rate
            return round(interest, 2)
        return 0.0

3. 多态调用(统一接口,不同行为)

def show_interest(account):
    """统一的函数,接收任何 Account 子类对象"""
    print(f"{account.owner} 的账户利息为:{account.calculate_interest()} 元")


# 创建不同类型的账户
savings = SavingsAccount("张三", 100000)
fixed = FixedDepositAccount("李四", 50000, 3)
credit = CreditCardAccount("王五", -5000)  # 欠款

# 多态调用:同一个函数,对不同对象表现出不同行为
show_interest(savings)   # 张三的账户利息为:9.59 元(活期按日计息)
show_interest(fixed)    # 李四的账户利息为:3750.0 元(定期三年)
show_interest(credit)   # 王五的账户利息为:2.5 元(信用卡欠款计息)
  • 统一接口show_interest(account)只关心对象有 calculate_interest方法,不关心它是活期、定期还是信用卡。

  • 易于扩展:如果新增一种账户类型(比如理财产品账户),只需继承 Account并实现自己的 calculate_interestshow_interest函数不用改。

  • 代码简洁:上层逻辑不需要写一堆 if isinstance(...)来判断账户类型,降低了耦合度。

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐