[Java 基础]面向对象-封装
封装是构建健壮、可维护和安全软件的基础。
什么是封装?
想象一下你的手机。你不需要知道手机内部复杂的电路、芯片和各种组件是如何协同工作的,你只需要知道如何使用屏幕、按键或触摸操作来打电话、发短信或玩游戏。手机的内部细节被“包裹”起来,只对外提供简洁易用的接口。
在面向对象编程中,封装的概念与之类似。它指的是将数据(属性/成员变量)和操作这些数据的方法(行为/成员方法)捆绑在一起,形成一个独立的单元(也就是我们之前学习的类)。同时,封装还涉及到控制类中成员的可见性,隐藏内部实现细节,只对外暴露必要的接口。
封装的主要目标:
- 数据隐藏 (Data Hiding): 保护对象内部的数据不被外部随意访问和修改,防止数据的意外损坏或不一致性。
- 接口隔离 (Interface Segregation): 向外部提供清晰、简洁的接口来操作对象,隐藏复杂的内部实现细节,降低外部代码与内部实现的耦合度。
- 提高代码的可维护性 (Maintainability): 当内部实现发生变化时,只要对外接口保持不变,就不会影响到使用该类的其他代码。这使得代码更容易修改和维护。
- 提高代码的安全性 (Security): 通过控制访问权限,可以限制对敏感数据的操作,增强程序的安全性。
- 代码重用 (Code Reusability): 封装良好的类可以作为独立的模块在不同的程序中重用。
如何在 Java 中实现封装?
在 Java 中,我们主要通过以下机制来实现封装:
- 使用访问修饰符 (Access Modifiers): Java 提供了不同的访问修饰符来控制类、成员变量和成员方法的可见性。常用的访问修饰符有:
public: 公有的,可以被任何类访问。
private: 私有的,只能在声明它的类内部访问。
protected: 受保护的,可以被声明它的类内部、同一个包中的其他类以及其子类访问。
默认(不写修饰符):包私有的,只能被声明它的类内部和同一个包中的其他类访问。
通常的做法是将类的成员变量声明为 private,以实现数据隐藏。
- 提供公共的访问方法 (Public Access Methods): 为了让外部代码能够操作私有的成员变量,我们需要提供公共的方法。常用的访问方法有:
Getter 方法 (获取器): 用于获取私有成员变量的值(通常以 get 开头,例如 getName())。
Setter 方法 (设置器): 用于修改私有成员变量的值(通常以 set 开头,例如 setAge(int newAge))。在 Setter 方法中,我们可以加入对输入值的合法性检查,从而保证数据的有效性。
代码示例:一个简单的 Person 类,让我们创建一个 Person 类来演示封装的概念:
public class Person {private String name; // 私有的姓名private int age; // 私有的年龄// 公有的构造方法public Person(String name, int age) {this.name = name;this.age = age;}// 公有的 Getter 方法获取姓名public String getName() {return name;}// 公有的 Setter 方法设置姓名public void setName(String newName) {if (newName != null && !newName.isEmpty()) {this.name = newName;} else {System.out.println("姓名不能为空!");}}// 公有的 Getter 方法获取年龄public int getAge() {return age;}// 公有的 Setter 方法设置年龄public void setAge(int newAge) {if (newAge >= 0 && newAge <= 150) { // 添加年龄合法性检查this.age = newAge;} else {System.out.println("年龄不合法!");}}// 公有的行为方法public void introduce() {System.out.println("大家好,我叫 " + name + ",今年 " + age + " 岁。");}public static void main(String[] args) {Person person1 = new Person("Alice", 25);System.out.println("姓名:" + person1.getName()); // 通过 Getter 方法获取姓名System.out.println("年龄:" + person1.getAge()); // 通过 Getter 方法获取年龄person1.setName("Bob"); // 通过 Setter 方法修改姓名person1.setAge(30); // 通过 Setter 方法修改年龄person1.introduce();// 尝试直接访问私有成员变量(会报错!)// System.out.println(person1.name);// person1.age = -10;}
}
封装是面向对象编程的核心概念之一。通过合理地使用访问修饰符和提供公共的访问方法,我们可以有效地隐藏类的内部实现细节,保护数据,提高代码的灵活性、可维护性和安全性。在设计类的时候,要养成将成员变量声明为 private 并提供公共的 Getter 和 Setter 方法的良好习惯。