📌 目录

  1. 什么是封装?
  2. 封装的特点
  3. 封装的实现
  4. 封装的优势
  5. 封装的应用场景
  6. 封装的实例化
  7. 封装的示例代码
  8. 参考资料
  9. 出站链接

1. 什么是封装?

封装(Encapsulation) 是面向对象编程中的一个基本特性,指将对象的状态(属性)和行为(方法)捆绑在一起,并通过对外提供的接口来访问对象的状态,从而隐藏对象的实现细节。封装有助于保护对象的内部状态,防止外部直接访问和修改。

封装的核心思想是将类的内部实现和外部暴露的接口分离,使得对象的内部实现对外部不可见,只能通过特定的访问方法进行操作。


2. 封装的特点

  1. 数据隐藏:通过访问修饰符控制属性和方法的可见性,使得外部无法直接访问对象的内部状态。
  2. 保护数据:通过封装,可以有效控制对数据的访问,防止外部修改对象的状态。
  3. 接口暴露:通过 getter 和 setter 方法暴露对象的状态,使外部可以通过这些方法来访问或修改对象的属性。
  4. 增强灵活性:通过修改 getter 和 setter 方法的实现,而不影响外部调用,增强了代码的灵活性。

3. 封装的实现

3.1 使用访问修饰符

在 Java 中,通过访问修饰符来控制类、属性和方法的访问权限。常用的访问修饰符有:

  • public:公有,任何地方都可以访问。
  • private:私有,只有类内部可以访问。
  • protected:受保护,子类和同一包中的类可以访问。
  • 默认(不写修饰符):包内可见,同一包中的类可以访问。

通过将类的属性设置为 private,外部无法直接访问,只有通过公共的 getter 和 setter 方法才能访问和修改。

3.2 提供getter和setter方法

通常,封装类中的属性会设置为 private,并通过 public 的 getter 和 setter 方法来提供对属性的访问。

  • getter 方法用于获取属性值。
  • setter 方法用于设置属性值。
public class Person {
    // 将属性设置为私有,无法直接访问
    private String name;
    private int age;

    // 获取 name 的 getter 方法
    public String getName() {
        return name;
    }

    // 设置 name 的 setter 方法
    public void setName(String name) {
        this.name = name;
    }

    // 获取 age 的 getter 方法
    public int getAge() {
        return age;
    }

    // 设置 age 的 setter 方法
    public void setAge(int age) {
        if (age >= 0) {  // 设置年龄时进行合法性检查
            this.age = age;
        } else {
            System.out.println("年龄不能为负数");
        }
    }
}

通过这种方式,外部可以使用 getter 和 setter 方法访问和修改 nameage 属性,而不能直接访问它们。通过 setter 方法,可以加入额外的逻辑(如合法性检查)。


4. 封装的优势

  1. 数据保护:封装可以防止外部直接访问对象的内部数据,防止数据被非法修改。
  2. 提高灵活性和可维护性:修改内部实现不会影响到外部调用者,只要 getter 和 setter 方法不变,外部代码就不会受到影响。
  3. 控制属性访问:可以在 setter 方法中增加额外的验证,确保数据的有效性和合法性。
  4. 增强可重用性:封装使得类的功能更独立,可以更容易地重用。

5. 封装的应用场景

  1. 安全性要求高的应用:封装保护敏感数据(如银行账户信息),防止外部未经授权的访问。
  2. 用户输入验证:通过 setter 方法验证输入数据的合法性,如年龄不允许为负数、用户名不为空等。
  3. 动态修改内部实现:封装允许你在不改变外部接口的情况下修改类的内部实现,提高代码的灵活性和可维护性。
  4. 大型软件项目:通过封装可以分离数据和操作,减少代码之间的耦合,提高代码模块化程度。

6. 封装的实例化

封装类的实例化与普通类一样,可以通过构造方法或 setter 方法为对象的属性赋值。在外部代码中,通过调用 getter 和 setter 方法来访问和修改对象的状态。

public class TestEncapsulation {
    public static void main(String[] args) {
        // 创建 Person 类的对象
        Person person = new Person();

        // 使用 setter 方法设置属性
        person.setName("John");
        person.setAge(30);

        // 使用 getter 方法获取属性
        System.out.println("Name: " + person.getName());
        System.out.println("Age: " + person.getAge());
    }
}

输出

Name: John
Age: 30


7. 封装的示例代码

示例 1:封装实现

public class Student {
    // 私有字段,不能直接访问
    private String name;
    private int grade;

    // 构造方法
    public Student(String name, int grade) {
        this.name = name;
        this.grade = grade;
    }

    // 获取学生姓名
    public String getName() {
        return name;
    }

    // 设置学生姓名
    public void setName(String name) {
        this.name = name;
    }

    // 获取学生成绩
    public int getGrade() {
        return grade;
    }

    // 设置学生成绩
    public void setGrade(int grade) {
        if (grade >= 0 && grade <= 100) {
            this.grade = grade;
        } else {
            System.out.println("成绩必须在 0 到 100 之间");
        }
    }

    // 显示学生信息
    public void displayInfo() {
        System.out.println("学生姓名: " + getName());
        System.out.println("学生成绩: " + getGrade());
    }
}

public class TestStudent {
    public static void main(String[] args) {
        Student student = new Student("Alice", 95);
        student.displayInfo();

        // 尝试设置无效成绩
        student.setGrade(110);  // 输出:成绩必须在 0 到 100 之间

        student.setGrade(85);
        student.displayInfo();  // 更新后输出学生信息
    }
}

输出

学生姓名: Alice
学生成绩: 95
成绩必须在 0 到 100 之间
学生姓名: Alice
学生成绩: 85


8. 参考资料


9. 出站链接