面试题答案
一键面试封装特性在C#实际项目场景中的应用示例
假设我们正在开发一个银行账户管理系统,其中有一个BankAccount
类。
public class BankAccount
{
// 私有字段,存储账户余额
private decimal balance;
// 构造函数,初始化账户余额
public BankAccount(decimal initialBalance)
{
if (initialBalance >= 0)
{
balance = initialBalance;
}
else
{
throw new ArgumentException("初始余额不能为负数", nameof(initialBalance));
}
}
// 公有方法,用于存款
public void Deposit(decimal amount)
{
if (amount > 0)
{
balance += amount;
}
else
{
throw new ArgumentException("存款金额必须为正数", nameof(amount));
}
}
// 公有方法,用于取款
public bool Withdraw(decimal amount)
{
if (amount > 0 && amount <= balance)
{
balance -= amount;
return true;
}
else
{
return false;
}
}
// 公有属性,用于获取账户余额(只读)
public decimal Balance
{
get { return balance; }
}
}
在上述代码中,balance
字段被声明为private
,外部代码无法直接访问和修改它。通过Deposit
和Withdraw
方法来控制对余额的操作,确保了数据的完整性和一致性。例如,存款金额必须为正数,取款金额不能超过当前余额等。同时,通过只读属性Balance
,外部代码只能获取余额,而不能直接修改。
这种应用体现封装优势的原因
- 数据隐藏:将
balance
字段设为私有,外部代码无法直接访问,避免了非法的数据修改。例如,如果外部代码可以直接访问balance
,可能会将余额设置为负数,这在银行账户场景中是不合理的。 - 数据保护:通过
Deposit
和Withdraw
方法的逻辑,可以对数据的修改进行验证和控制。比如取款时检查余额是否足够,从而保护了账户数据的完整性。 - 提高安全性:外部代码只能通过定义好的接口(公有方法和属性)来与对象交互,减少了因错误的直接数据访问而导致的程序错误,提高了系统的安全性和稳定性。
- 代码维护和可扩展性:如果需要修改余额的存储方式或者对余额操作的逻辑,只需要在类内部进行修改,而不会影响到外部使用该类的代码。例如,如果未来需要记录每笔交易,只需要在
Deposit
和Withdraw
方法中添加相应的逻辑,而不会对使用BankAccount
类的其他部分造成影响。