12 封装与构造方法 目录 12 封装与构造方法12.1 为什么要封装12.2 private关键字访问修饰符对比使用private修饰成员变量12.3 getter与setter方法12.3.1 基本写法12.3.2 使用getter/setter12.3.3 只读属性与只写属性12.4 this关键字12.4.1 问题引出12.4.2 this的含义12.4.3 this的常见用法12.4.4 完整示例12.5 构造方法12.5.1 什么是构造方法12.5.2 构造方法的特点12.5.3 定义构造方法12.5.4 带参构造方法12.6 构造方法重载this()调用其他构造方法12.7 JavaBean规范JavaBean规范标准JavaBean示例12.8 综合案例学生管理系统需求代码实现12.9 本章总结知识回顾练习题 互动时间 参考资料 12 封装与构造方法更新日期2026年5月版权声明本文为原创内容转载请注明出处。系列Java入门到精通系列 · 第二阶段 · 面向对象12.1 为什么要封装上一章中我们可以直接访问和修改对象的属性StudentstunewStudent();stu.age-100;// 合法但不合理问题外部代码可以随意修改数据没有安全保障。封装的核心思想隐藏内部实现细节只暴露必要的接口给外部使用。问题封装前封装后数据安全外部可直接修改通过方法控制访问数据校验无法校验在setter中校验代码耦合外部依赖内部实现外部只依赖接口可维护性修改内部影响外部修改内部不影响外部12.2 private关键字private是一个访问修饰符用于修饰成员变量和成员方法使其只能在本类内部被访问。访问修饰符对比修饰符同类同包子类不同包public✅✅✅✅protected✅✅✅❌默认不写✅✅❌❌private✅❌❌❌使用private修饰成员变量publicclassStudent{privateStringname;// 私有化privateintage;// 私有化privatedoublescore;// 私有化}此时在外部直接访问会编译报错StudentstunewStudent();stu.name张三;// ❌ 编译错误name是private的12.3 getter与setter方法为了在保护数据的同时允许外部访问我们提供公开的getter/setter方法。12.3.1 基本写法publicclassStudent{privateStringname;privateintage;privatedoublescore;// ---- getter方法 ----publicStringgetName(){returnname;}publicintgetAge(){returnage;}publicdoublegetScore(){returnscore;}// ---- setter方法带数据校验----publicvoidsetName(Stringname){this.namename;}publicvoidsetAge(intage){if(age0||age150){System.out.println(年龄不合法);return;}this.ageage;}publicvoidsetScore(doublescore){if(score0||score100){System.out.println(成绩必须在0-100之间);return;}this.scorescore;}}12.3.2 使用getter/setterpublicclassStudentTest{publicstaticvoidmain(String[]args){StudentstunewStudent();stu.setName(张三);stu.setAge(20);stu.setScore(95.5);System.out.println(姓名stu.getName());System.out.println(年龄stu.getAge());System.out.println(成绩stu.getScore());// 测试数据校验stu.setAge(-100);// 输出年龄不合法stu.setScore(150);// 输出成绩必须在0-100之间}}12.3.3 只读属性与只写属性publicclassUser{privateStringusername;privateStringpassword;// username可读可写publicStringgetUsername(){returnusername;}publicvoidsetUsername(Stringusername){this.usernameusername;}// password只写没有getter外部无法读取publicvoidsetPassword(Stringpassword){this.passwordpassword;}// 内部可以使用passwordpublicbooleancheckPassword(Stringinput){returnthis.password.equals(input);}}12.4 this关键字12.4.1 问题引出publicvoidsetAge(intage){ageage;// 两个age都是局部变量成员变量没被赋值}当成员变量和局部变量同名时Java会就近原则优先使用局部变量。12.4.2 this的含义this代表当前对象的引用即调用该方法的对象。publicvoidsetAge(intage){this.ageage;// this.age是成员变量age是局部变量}12.4.3 this的常见用法用法说明示例区分同名变量this.成员变量this.name name调用本类方法this.方法名()this.show()调用构造方法this(参数)this(, 0)12.4.4 完整示例publicclassPerson{privateStringname;privateintage;publicPerson(Stringname,intage){this.namename;// this.name是成员变量this.ageage;// this.age是成员变量}publicvoidshow(){System.out.println(namethis.name, agethis.age);}publicvoidcompareAge(Personother){if(this.ageother.age){System.out.println(this.name比other.name大);}elseif(this.ageother.age){System.out.println(this.name比other.name小);}else{System.out.println(this.name和other.name同龄);}}}12.5 构造方法12.5.1 什么是构造方法构造方法Constructor是一种特殊的方法用于在创建对象时初始化对象的成员变量。newStudent();// 这里调用的就是构造方法12.5.2 构造方法的特点特点说明方法名必须与类名完全相同返回值没有返回值类型连void都没有调用时机new的时候自动调用只调用一次作用初始化成员变量默认如果不写编译器会自动提供一个无参构造12.5.3 定义构造方法publicclassStudent{privateStringname;privateintage;// 无参构造方法publicStudent(){System.out.println(Student对象被创建了);}// getter/setter省略...}publicclassTest{publicstaticvoidmain(String[]args){StudentstunewStudent();// 控制台输出Student对象被创建了}}12.5.4 带参构造方法publicclassStudent{privateStringname;privateintage;privatedoublescore;// 带参构造方法publicStudent(Stringname,intage,doublescore){this.namename;this.ageage;this.scorescore;}// getter/setter省略...publicvoidshow(){System.out.println(nameage岁成绩score);}}StudentstunewStudent(张三,20,95.5);stu.show();// 输出张三20岁成绩95.5重要提醒一旦你写了任何构造方法编译器就不再自动提供无参构造。建议永远手动写上无参构造。12.6 构造方法重载一个类可以有多个构造方法参数列表不同即可。publicclassStudent{privateStringname;privateintage;privatedoublescore;// 无参构造publicStudent(){this(未知,0,0);// 调用三参构造}// 两参构造publicStudent(Stringname,intage){this(name,age,0);// 调用三参构造}// 三参构造全参构造publicStudent(Stringname,intage,doublescore){this.namename;this.ageage;this.scorescore;}publicvoidshow(){System.out.println(nameage岁成绩score);}}调用示例Students1newStudent();// 未知0岁成绩0.0Students2newStudent(张三,20);// 张三20岁成绩0.0Students3newStudent(李四,21,92.5);// 李四21岁成绩92.5s1.show();s2.show();s3.show();this()调用其他构造方法publicStudent(){this(未知,0,0);// 必须是构造方法的第一行}this(参数)只能在构造方法中使用且必须是第一行语句。不能和super()同时出现。12.7 JavaBean规范JavaBean是一种符合特定编写规范的Java类广泛用于企业级开发。JavaBean规范规则说明类必须是public公开访问成员变量必须private私有化必须有无参构造方法便于框架反射创建对象必须有getter/setter方法通过方法访问属性实现Serializable接口可序列化推荐标准JavaBean示例importjava.io.Serializable;publicclassStudentimplementsSerializable{privatestaticfinallongserialVersionUID1L;privateStringname;privateintage;privatedoublescore;// 无参构造publicStudent(){}// 全参构造publicStudent(Stringname,intage,doublescore){this.namename;this.ageage;this.scorescore;}// getter/setterpublicStringgetName(){returnname;}publicvoidsetName(Stringname){this.namename;}publicintgetAge(){returnage;}publicvoidsetAge(intage){this.ageage;}publicdoublegetScore(){returnscore;}publicvoidsetScore(doublescore){this.scorescore;}// toStringOverridepublicStringtoString(){returnStudent{namename, ageage, scorescore};}} 在实际开发中我们常用Lombok的Data、Getter、Setter、AllArgsConstructor、NoArgsConstructor注解来自动生成getter/setter和构造方法减少样板代码。12.8 综合案例学生管理系统需求设计一个简单的学生类要求使用private封装所有属性提供有参和无参构造方法在setter中进行数据校验提供一个显示信息的方法代码实现publicclassStudent{privateStringname;privateintage;privateStringmajor;privatedoublegpa;// 无参构造publicStudent(){}// 全参构造publicStudent(Stringname,intage,Stringmajor,doublegpa){this.setName(name);this.setAge(age);this.setMajor(major);this.setGpa(gpa);}// getter/setter带校验publicStringgetName(){returnname;}publicvoidsetName(Stringname){if(namenull||name.trim().isEmpty()){System.out.println(姓名不能为空);return;}this.namename;}publicintgetAge(){returnage;}publicvoidsetAge(intage){if(age15||age60){System.out.println(年龄必须在15-60之间);return;}this.ageage;}publicStringgetMajor(){returnmajor;}publicvoidsetMajor(Stringmajor){this.majormajor;}publicdoublegetGpa(){returngpa;}publicvoidsetGpa(doublegpa){if(gpa0.0||gpa4.0){System.out.println(GPA必须在0.0-4.0之间);return;}this.gpagpa;}// 显示信息publicStringgetInfo(){return姓名name | 年龄age | 专业major | GPAgpa;}// 判断是否优秀publicbooleanisExcellent(){returnthis.gpa3.5;}OverridepublicStringtoString(){returngetInfo();}}测试类publicclassStudentManager{publicstaticvoidmain(String[]args){// 使用全参构造创建学生Students1newStudent(张三,20,计算机科学,3.8);Students2newStudent(李四,21,软件工程,3.2);Students3newStudent(王五,19,人工智能,3.9);// 使用无参构造 setter创建学生Students4newStudent();s4.setName(赵六);s4.setAge(22);s4.setMajor(数据科学);s4.setGpa(3.6);// 存入数组统一管理Student[]students{s1,s2,s3,s4};System.out.println( 学生信息 );for(Students:students){System.out.println(s.getInfo());System.out.println(是否优秀(s.isExcellent()?✅ 是:❌ 否));System.out.println(------------------------------);}// 测试数据校验Students5newStudent();s5.setAge(10);// 输出年龄必须在15-60之间s5.setGpa(5.0);// 输出GPA必须在0.0-4.0之间}}输出结果 学生信息 姓名张三 | 年龄20 | 专业计算机科学 | GPA3.8 是否优秀✅ 是 ------------------------------ 姓名李四 | 年龄21 | 专业软件工程 | GPA3.2 是否优秀❌ 否 ------------------------------ 姓名王五 | 年龄19 | 专业人工智能 | GPA3.9 是否优秀✅ 是 ------------------------------ 姓名赵六 | 年龄22 | 专业数据科学 | GPA3.6 是否优秀✅ 是 ------------------------------ 年龄必须在15-60之间 GPA必须在0.0-4.0之间12.9 本章总结知识回顾知识点核心内容封装隐藏实现细节只暴露必要接口private修饰成员变量/方法只在本类可访问getter/setter公开的访问方法可在setter中做校验this关键字代表当前对象引用区分同名变量构造方法与类同名、无返回值、new时调用构造方法重载多个构造方法参数不同JavaBeanprivate属性 getter/setter 无参构造 Serializable练习题定义一个BankAccount类银行账户要求属性账号(accountNo)、户主名(ownerName)、余额(balance)balance只能通过deposit(存款)和withdraw(取款)方法修改withdraw需要校验余额是否充足提供showBalance()方法显示余额定义一个Rectangle类矩形要求属性长(length)、宽(width)必须为正数提供无参和有参构造方法提供计算面积和周长的方法 互动时间为什么JavaBean要求必须有无参构造方法this关键字有几种用法分别在什么场景下使用下篇预告[13-继承]—— 学习如何用继承实现代码复用以及方法重写的奥秘 参考资料Oracle Java 官方文档 - Controlling AccessJavaBean 规范《Java核心技术 卷I》第4章