- 构造方法: 别称构造函数, 构造器, Constructor
- 作用:用于给对象成员变量赋值.在创建对象的同时,会自动调用构造方法,等对象创建完成时,可以对对象中的成员变量赋值.
- 构造方法的格式:
修饰符 方法名称(参数列表){
方法体;
}
- 构造方法的格式说明
- 构造方法的方法名, 必须要类名一模一样,连大小写都要一样
- 构造方法没有返回值, 连void都不要写
- 构造方法没有return语句, 如果一定要写return, 就只写一个return; 提前结束构造方法
5.构造方法的使用说明
1.构造方法不需要手动调用,因为构造方法是在创建对象的时候由jvm自动调用
2.不要使用对象名调用构造方法
3.创建一个对象只调用一次构造方法
实例代码
class 构造方法_01 {
public static void main(String[] args) {
Person p = new Person();
System.out.println(p.getName());
System.out.println(p.getAge());
Person p2 = new Person(); //此时是创建第二个对象
System.out.println(p2.getName());
System.out.println(p2.getAge());
Person p3 = new Person(); //此时是创建第二个对象
System.out.println(p3.getName());
System.out.println(p3.getAge());
// p.Person(); 编译报错, 构造方法不能使用对象调用
}
}
class Person{
private String name;
private int age;
/*
修饰符 方法名(参数列表){
方法体
}
*/
// 最简单的构造方法: 空参构造方法
public Person(){
// System.out.println("创建对象的时候回自动调用");
name = "史祥";
age = 18;
}
public void setName(String name){
this.name = name;
}
public String getName(){
return name;
}
public void setAge(int age){
this.age = age;
}
public int getAge(){
return age;
}
}
构造方法的注意事项
- 构造方法既可以有参数,也可以没有参数
如果是没有参数的构造方法,外界就无法通过构造方法传递数据.我们只能在构造方法中,把要给成员变量赋的值写死,不灵活;
如果是有参数的构造方法,外界在调用构造方法的时候,就可以通过传入参数的方法,动态的给成员变量赋值, 这种比较灵活;
- 如果我们创建一个类,系统会给这个类提供一个默认的无参数构造方法; 但是如果我们自己写了其他的构造方法,系统就不再为我们写的类提供无参数构造方法了;
- 构造方法的重载
重新定义:一个类中,方法名相同,参数列表不同(类型,顺序, 个数),与返回值类型无关,参数名无关
所有构造方法都在同一类中,构造方法的名字都和类名一致,只是参数列表不同,没有返回值.所以多个构造方法就是方法的重载;
- 一个类中,即使你不使用无参数构造方法,也要把无参数构造方法写上; 不管你写没写其他构造方法,都要写上;
实例代码
class 构造方法的注意事项_02 {
public static void main(String[] args) {
Person p = new Person("宝宝");
p.show();
Person p2 = new Person();
p2.show();
Person p3 = new Person(18);
p3.show();
Person p4 = new Person("祥哥", 18);
p4.show();
}
}
class Person {
private String name;
private int age;
// 如果自己写了其他构造方法,还想用空参构造方法,需要自己手动添加
public Person(){
System.out.println("无参数构造方法,空参构造方法");
}
// 准备有参数的构造方法
// 有一个参数的构造方法, 用来给name赋值
public Person(String name){
this.name = name;
}
// 有一个参数的构造方法, 用来给age赋值
public Person(int age){
this.age = age;
}
// 有两个参数的构造方法, 给name和age赋值
public Person(String name, int age){
this.name = name;
this.age = age;
}
public Person(int age, String name){
this.name = name;
this.age = age;
}
public void show(){
System.out.println("姓名:"+name+ ", 年龄:"+age);
}
public void setName(String name){
this.name = name;
}
public String getName(){
return name;
}
public void setAge(int age){
this.age = age;
}
public int getAge(){
return age;
}
}
构造方法和Setter方法比较
- 相同点:都可以给私有的成员变量赋值, 目的都是为了不想外界直接访问成员变量,通过这两种方式间接的操作私有的成员变量
- 区别:
构造方法的调用时机: 是在创建对象的同时,由jvm自动调用, 只执行一次
Setter方法调用时机: 一定是对象创建完成之后,由对象手动调用,用于修改成员变量中值,可以调用多次
- 使用场景
构造方法是用场景:
当创建一个对象的时候,就需要给成员变量赋值,就使用构造方法.而且创建对象也不想再去修改成员变量中的值了;
Setter方法使用场景: 使用于需要先创建对象,后赋值的情况,Setter方法相比构造方法更加的灵活;
实例代码
class 构造方法和Setter方法比较_03 {
public static void main(String[] args) {
// 构造方法
// 父母已经想好名字了
Person p = new Person("强强", 1);
// 一年后
p.setAge(2);
p.show();
// 父母没有想好名字
Person p2 = new Person();
// 一年后想好了
p2.setName("舒豪");
p2.setAge(2);
// 两年后
p2.setAge(4);
p2.show();
}
}
class Person {
private String name = "逗比";
private int age;
public Person(){
System.out.println("无参数构造方法,空参构造方法");
}
public Person(String name){
this.name = name;
}
public Person(int age){
this.age = age;
}
public Person(String name, int age){
this.name = name;
this.age = age;
}
public Person(int age, String name){
this.name = name;
this.age = age;
}
public void show(){
System.out.println("姓名:"+name+ ", 年龄:"+age);
}
public void setName(String name){
this.name = name;
}
public String getName(){
return name;
}
public void setAge(int age){
this.age = age;
}
public int getAge(){
return age;
}
}
创建对象时成员变量赋值的方式
- 创建对象时给成员赋值的方式有三种:
默认初始化;
显示初始化;
构造方法初始化;
- 默认初始化: 就是没有自己没有给成员赋值,系统赋的默认值: 引用类型 null, 整型:0 小数:0.0 布尔:false, 字符: ‘u0000’
- 显示初始化: 就是在定义成员变量的时候,就给成员变量赋值
- 构造方法初始化: 通过构造方法的方式给成员变量赋值
- 三种给成员变量赋值的顺序: 赋值的晚的会把赋值早的给覆盖掉
通过空参数构造方法,可以校验得到默认初始化早于显示初始化;
通过有参数构造方法,可以校验得到显示初始化早于构造方法初始化;
三种初始化的顺序:
默认初始化 > 显示初始化 > 构造方法初始化
- 创建对象流程:
- 将对象所属类的..class文件加载到方法区
- 在栈内存中创建一个该对象引用(对象名),用来存储对象在堆区的地址
- 在堆区开辟内存空间,给每个成员变量分配空间
- 默认初始化先给成员变量赋值
- 显示初始化再给成员变量赋值
- 通过构造方法给成员变量赋值
- 最后把堆区对象的地址赋值给栈内存中对象名
图示
实例代码
class 创建对象时成员变量赋值的方式_04 {
public static void main(String[] args) {
// 验证 显示初始化和默认初始化
Person p = new Person();
p.show();
// 验证: 构造方法初始化和显示初始化
Person p2 = new Person("宝宝", 18);
p2.show();
}
}
class Person {
// 显示初始化
private String name = "庆朝";
private int age = 38;
public Person(){
}
public Person(String name, int age){
this.name = name;
this.age = age;
}
public void show(){
System.out.println("姓名:"+name+ ", 年龄:"+age);
}
}
- 没有使用静态时,当一个类中某个属性,每个对象所有值都是同一个值,那么这个属性就会在每个对象堆区空间中申请一块空间来存储成员变量,此时会造成空间的浪费; 后期维护难度比较大.
图示