「 Java 面向对象系列 05 」
📖上篇回顾:Java 面向对象核心入门(四):封装实战「getter & setter 方法」-CSDN博客
本篇引入
前面我们学会了:
- 使用
private私有化属性 - 使用
getter / setter读写属性 - 在
setter中进行数据校验
但如果创建一个对象后,要连续调用很多setter,代码会显得比较啰嗦。
比如:
Studentstu=newStudent();stu.setName("张三");stu.setAge(18);stu.setScore(95.5);有没有办法在创建对象的时候,就直接把属性赋值好?
答案就是:构造方法 Constructor。
一、什么是构造方法?
构造方法是一种特殊的方法,作用是:创建对象时,给对象的属性初始化赋值。
1.构造方法的语法特点
- 方法名必须和类名完全一致
- 没有返回值类型,连
void也不写 - 在执行
new 类名()时自动调用
2.示例
classStudent{privateStringname;privateintage;privatedoublescore;// 构造方法:创建对象时初始化属性publicStudent(Stringname,intage,doublescore){this.name=name;this.age=age;this.score=score;}}二、使用构造方法创建对象
有了构造方法后,创建对象就可以这样写:
Studentstu=newStudent("张三",18,95.5);创建对象时,参数会自动传给构造方法,然后在构造方法里完成属性赋值。
完整示例
classStudent{privateStringname;privateintage;privatedoublescore;publicStudent(Stringname,intage,doublescore){this.name=name;this.age=age;this.score=score;}publicStringgetName(){returnname;}publicintgetAge(){returnage;}publicdoublegetScore(){returnscore;}}publicclassTestStudent{publicstaticvoidmain(String[]args){Studentstu=newStudent("张三",18,95.5);System.out.println(stu.getName());System.out.println(stu.getAge());System.out.println(stu.getScore());}}运行输出:
张三 18 95.5三、构造方法的好处
没有构造方法时:
Studentstu=newStudent();stu.setName("张三");stu.setAge(18);stu.setScore(95.5);有了构造方法后:
Studentstu=newStudent("张三",18,95.5);可以看出,构造方法的核心好处是:创建对象时一次性完成属性初始化,减少重复代码,提高开发效率。
同时也能保证对象创建出来后,关键属性已经有值,避免对象处于 “属性为空但应该有值” 的状态。
四、默认构造方法
如果我们没有手动写任何构造方法,Java 会自动提供一个无参构造方法。
例如:
classStudent{privateStringname;privateintage;}等价于:
classStudent{privateStringname;privateintage;publicStudent(){}}所以下面代码可以正常运行:
Studentstu=newStudent();但是注意:只要你手动写了一个有参构造方法,Java 就不会再自动提供无参构造方法。
例如:
classStudent{privateStringname;publicStudent(Stringname){this.name=name;}}此时再写:
Studentstu=newStudent();就会报错。
原因是:你已经提供了有参构造方法,Java 认为你已经指定了对象创建方式,所以不再自动补充无参构造。
五、无参构造方法的作用
无参构造方法通常用于:
- 创建一个 “空对象”
- 对象创建后再通过
setter逐个赋值 - 子类继承父类时,父类需要有无参构造方法
示例:
classStudent{privateStringname;privateintage;// 无参构造方法publicStudent(){}// 有参构造方法publicStudent(Stringname,intage){this.name=name;this.age=age;}}这样下面两种创建方式都可以使用:
Studentstu1=newStudent();stu1.setName("张三");Studentstu2=newStudent("李四",20);六、一个类中可以有多个构造方法吗?
可以。
一个类中可以定义多个构造方法,但它们的参数列表必须不同。
这属于方法重载的一种。
示例:
classStudent{privateStringname;privateintage;// 无参构造publicStudent(){}// 一个参数的构造publicStudent(Stringname){this.name=name;}// 两个参数的构造publicStudent(Stringname,intage){this.name=name;this.age=age;}}创建对象时:
Studentstu1=newStudent();Studentstu2=newStudent("张三");Studentstu3=newStudent("李四",20);编译器会根据传入参数的数量和类型,自动调用对应的构造方法。
七、构造方法和普通方法的区别
很多新手容易把构造方法和普通方法搞混。
| 区别 | 构造方法 | 普通方法 |
|---|---|---|
| 作用 | 创建对象并初始化属性 | 表示对象的行为功能 |
| 方法名 | 必须和类名相同 | 可以自定义 |
| 返回值 | 没有返回值,连void也不写 | 必须声明返回值类型 |
| 调用时机 | new 对象()时自动调用 | 对象创建后手动调用 |
| 是否需要显式定义 | 不写则默认提供无参构造 | 必须手动定义 |
示例对比:
classStudent{// 构造方法publicStudent(){}// 普通方法publicvoidstudy(){System.out.println("学生正在学习");}}使用:
Studentstu=newStudent();// 调用构造方法stu.study();// 调用普通方法八、构造方法里也可以做校验
构造方法不只是用来赋值,也可以做数据校验。
例如:
classStudent{privateintage;publicStudent(intage){if(age>0&&age<=120){this.age=age;}else{System.out.println("年龄不合法");}}publicintgetAge(){returnage;}}测试:
Studentstu=newStudent(-5);System.out.println(stu.getAge());运行输出:
年龄不合法 0这里年龄没有被赋值,所以成员变量会保持默认值0。
注意:构造方法可以做简单校验,但对象创建后,外部仍可能通过
setter修改数据,所以真正的数据保护需要构造方法和setter协同工作。
九、新手高频误区
1. 构造方法名和类名不一致
错误写法:
publicstudent(){}正确写法:
publicStudent(){}Java 是大小写敏感的,类名和构造方法名必须完全一致。
2. 给构造方法写返回值
错误写法:
publicvoidStudent(){}正确写法:
publicStudent(){}构造方法没有返回值,连void也不能写。
3. 写了有参构造,还想继续使用无参构造
错误场景:
classStudent{publicStudent(Stringname){}}Studentstu=newStudent();会报错。
解决办法:手动补充无参构造方法
classStudent{publicStudent(){}publicStudent(Stringname){}}4. 把构造方法当成普通方法调用
错误写法:
Studentstu=newStudent();stu.Student();构造方法不是普通方法,不能在对象创建后再手动调用。
它只在new对象时自动执行一次。
十、IDEA一键生成构造方法(开发实操)
实际开发工作里,很少手动敲完整构造方法,使用IDEA快捷键一键生成,代码规范还能避免手写bug。
快捷键
- Windows / Linux:
Alt + Insert - Mac:
Command + N
操作步骤
- 先定义好类中全部 private 私有成员变量
- 在类的大括号内空白位置按下快捷键
Alt + Insert,选择Constructor(构造方法) - 生成无参构造:不勾选任何成员,直接确定
- 生成有参构造:勾选需要参与初始化的成员变量,确认生成
✨重点:IDEA自动生成的有参构造,会自动补好
this.属性 = 参数,完美解决参数和成员变量重名赋值失效的问题。
💡补充:同一个快捷键,还可以快速生成 getter、setter 方法,属于Java后端高频快捷键,建议记牢。
十一、全文核心小结
- 构造方法的作用是:创建对象时给属性初始化赋值。
- 构造方法名必须和类名相同,没有返回值类型。
- 使用
new 类名(参数)创建对象时,会自动调用对应的构造方法。 - 如果没有手动写构造方法,Java 会自动提供无参构造方法。
- 如果写了有参构造方法,Java 不再自动提供无参构造方法。
- 一个类可以有多个构造方法,形成构造方法重载。
- 构造方法主要负责对象初始化,真正的数据校验需要构造方法和
setter协同工作。
本篇代码练习
可以让类同时具备:
- 无参构造方法
- 有参构造方法
getter / setter- 年龄校验
参考代码:
classStudent{privateStringname;privateintage;publicStudent(){}publicStudent(Stringname,intage){this.name=name;if(age>0&&age<=120){this.age=age;}else{System.out.println("年龄不合法");}}publicStringgetName(){returnname;}publicvoidsetName(Stringname){this.name=name;}publicintgetAge(){returnage;}publicvoidsetAge(intage){if(age>0&&age<=120){this.age=age;}else{System.out.println("年龄不合法");}}}