面向对象三大特性---封装
面向对象三大特性—封装
什么是封装?
封装说白了就是把东西包起来,不让外人随便碰。就像你的手机,虽然内部有复杂的电路板、芯片,但厂商把这些都封装在外壳里,你只需要通过屏幕和按钮来操作,不需要直接接触内部零件。
为什么需要封装?
- 保护数据安全:想象一下,如果银行账户的余额可以被任何人随意修改,那会是什么后果?封装就是给数据加了一把锁。
- 隐藏实现细节:你开车的时候,只需要知道踩油门就能加速,不需要了解发动机是怎么工作的。同样,使用一个类的时候,只需要知道它提供了什么功能,不需要关心内部是怎么实现的。
- 提高代码的可维护性:如果内部实现需要修改,只要对外提供的接口不变,其他代码就不需要跟着改。。
public class BankAccount {// 私有属性,外部无法直接访问private String accountNumber;private String ownerName;private double balance;// 构造方法public BankAccount(String accountNumber, String ownerName, double initialBalance) {this.accountNumber = accountNumber;this.ownerName = ownerName;// 这里可以加入验证逻辑if (initialBalance >= 0) {this.balance = initialBalance;} else {this.balance = 0;}}// 公共方法:存钱public void deposit(double amount) {if (amount > 0) {balance += amount;System.out.println("存入 " + amount + " 元,当前余额:" + balance);} else {System.out.println("存款金额必须大于0");}}// 公共方法:取钱public boolean withdraw(double amount) {if (amount > 0 && amount <= balance) {balance -= amount;System.out.println("取出 " + amount + " 元,当前余额:" + balance);return true;} else {System.out.println("取款失败:金额不正确或余额不足");return false;}}// 公共方法:查询余额public double getBalance() {return balance;}}
访问修饰符详解
Java提供了四种访问修饰符来控制访问权限:
访问修饰符 | 同一个类 | 同一个包 | 不同包的子类 | 不同包的非子类 | 使用场景 |
---|---|---|---|---|---|
private | ✅ | ❌ | ❌ | ❌ | 类的内部数据,不希望外部访问 |
default(包私有) | ✅ | ✅ | ❌ | ❌ | 包内共享的工具方法或数据 |
protected | ✅ | ✅ | ✅ | ❌ | 希望子类能访问的属性或方法 |
public | ✅ | ✅ | ✅ | ✅ | 对外提供的公共接口 |
选择访问修饰符的原则:
- 最小权限原则:优先使用限制性最强的访问修饰符
- private优先:类的内部数据尽量使用private
- public谨慎:只有确实需要对外提供的接口才用public
- protected适中:主要用于继承体系中父类与子类的交互
- default罕见:现在很少单独使用,多数情况下要么private要么public
getter和setter方法
有时候我们需要让外部能够访问或修改私有属性,但又要加上一些控制逻辑,这时候就用getter和setter方法:
public class Person {private String name;private int age;// getter方法:获取姓名public String getName() {return name;}// setter方法:设置姓名public void setName(String name) {if (name != null && !name.trim().isEmpty()) {this.name = name;} else {System.out.println("姓名不能为空");}}// getter方法:获取年龄public int getAge() {return age;}// setter方法:设置年龄public void setAge(int age) {if (age >= 0 && age <= 150) {this.age = age;} else {System.out.println("年龄必须在0-150之间");}}
}
封装的好处
- 数据安全:private属性无法被外部直接修改,避免了数据被恶意篡改
- 数据验证:通过setter方法可以对输入的数据进行验证
- 代码维护:修改类的内部实现不会影响外部代码
- 接口清晰:外部只需要知道public方法,不需要了解内部细节
常见误区
误区1:所有属性都要private
不是的,要根据实际需求来决定。比如一些常量可以是public的。
误区2:每个private属性都要有getter和setter
也不是的,有些属性可能只需要getter,有些甚至都不需要。要根据业务逻辑来决定。
误区3:封装就是隐藏所有东西
封装的目的是合理地控制访问权限,该公开的要公开,该隐藏的要隐藏。