Java 封装之应用技巧
封装是面向对象编程的三大特性之一,其核心在于隐藏对象的内部细节,仅对外暴露必要的接口。通过封装,可以提高代码的安全性、可维护性和复用性。以下是封装在实际开发中的应用技巧及代码示例。
使用私有字段与公共方法
私有字段是封装的基础,通过公共方法(Getter/Setter)控制对字段的访问和修改,可以在方法中添加逻辑验证。
public class Person {
private String name;
private int age;
public String getName() {
return name;
}
public void setName(String name) {
if (name == null || name.trim().isEmpty()) {
throw new IllegalArgumentException("Name cannot be empty");
}
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
if (age < 0 || age > 150) {
throw new IllegalArgumentException("Invalid age");
}
this.age = age;
}
}
封装复杂逻辑
将复杂逻辑隐藏在类内部,对外提供简洁的接口。例如,计算圆面积的逻辑封装在类中,调用者只需提供半径。
public class Circle {
private double radius;
public Circle(double radius) {
if (radius <= 0) {
throw new IllegalArgumentException("Radius must be positive");
}
this.radius = radius;
}
public double getArea() {
return Math.PI * radius * radius;
}
}
不可变类的封装
通过移除Setter方法并设置字段为final,可以创建不可变类,确保对象状态不会被修改。
public final class ImmutablePerson {
private final String name;
private final int age;
public ImmutablePerson(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public int getAge() {
return age;
}
}
封装集合字段
直接暴露集合字段可能导致外部代码随意修改集合内容。通过返回集合的副本或不可变视图,可以保护内部数据。
import java.util.Collections;
import java.util.List;
public class Team {
private List<String> members;
public Team(List<String> members) {
this.members = members;
}
public List<String> getMembers() {
return Collections.unmodifiableList(members);
}
public void addMember(String member) {
members.add(member);
}
}
封装工具方法
将常用的工具方法封装在类中,避免重复代码。例如,字符串处理的工具类。
public class StringUtils {
public static boolean isBlank(String str) {
return str == null || str.trim().isEmpty();
}
public static String capitalize(String str) {
if (isBlank(str)) {
return str;
}
return str.substring(0, 1).toUpperCase() + str.substring(1);
}
}
封装与设计模式
封装在多种设计模式中发挥重要作用。例如,单例模式通过封装构造方法确保只有一个实例。
public class Singleton {
private static Singleton instance;
private Singleton() {}
public static synchronized Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
通过接口进一步封装
接口可以隐藏实现细节,调用者只需关注接口定义的方法。
public interface DataService {
String fetchData();
}
public class DatabaseService implements DataService {
@Override
public String fetchData() {
return "Data from database";
}
}
public class APIService implements DataService {
@Override
public String fetchData() {
return "Data from API";
}
}
通过以上技巧,可以充分发挥封装的优势,构建更安全、更灵活的Java应用程序。