社交媒体

封装

封装

钩子:你的对象在"裸奔"

接着上篇的 Student 类,现在写个"破坏者":

Student s = new Student("张三", 18);
s.age = -100;      // 编译通过,运行不报错
s.name = null;     // 名字也能直接抹掉

一个对象,年龄 -100,名字 null——它还是个合法对象。

问题出在哪?字段是 public(默认可随便访问)的,谁都能拿笔直接往"出生证明"上改数字。现实中不会这样,是因为数据藏在系统的内部,外部只能走柜台。

这个"柜台",就是封装。

核心:三个词,守住对象的大门

第一步:private——把字段锁起来

class Student {
    private String name;    // 只能本类访问
    private int age;
}

加上 private 之后,s.age = -100 直接编译报错:"age 在 Student 中是 private 访问控制"。外部世界的手,被挡在门外了。

第二步:getter——提供"查看窗口"

public String getName() {
    return name;
}

外部想看名字,走这个方法。看,可以;直接改,不行。

第三步:setter——提供"审核过的修改窗口"

public void setAge(int age) {
    if (age < 0 || age > 150) {
        System.out.println("年龄不合法,已忽略");
        return;             // 不合法的值,进不来
    }
    this.age = age;
}

关键就在这里:外部只能通过方法改数据,而方法里可以写校验逻辑。setAge(-100) 会被拦下——负岁数的闹剧,到此为止。

17-封装防护图.png

你天天在用,只是没人告诉你

看到 getter/setter 的样子,是不是很眼熟?

  • IDEA 里右键 → Generate → Getter and Setter,一键生成的那堆代码,就是今天这套东西;
  • 你写过的 s.getName()、list.size(),全是"读窗口";
  • 第 4 篇说"看懂 IDEA 自动生成的代码",加上第 16 篇的 this 和今天的 getter/setter,那个谜基本解完了。

一个度的问题

新手常问:那我把所有字段全 private + 全套 getter/setter,对吗?

分两种情况:

  1. age、name 这种"有业务规则"的字段——必须封装,setter 里写校验,这是封装的价值所在;
  2. 纯数据搬运类(后面学到的实体类)——全封装 + 自动生成即可,校验由更上层负责。

一句话:封装不是为了"藏",是为了"改数据必须过审核"。三大特性里,继承和多态更炫,但封装是最先该养成的习惯。


本文示例代码均已本地实测通过,可直接运行。
对应文件:EncapDemo.java


橙码酱,分享更有用的技术知识,助你成为更优秀的开发者。