-
构造器的名称必须和类名一致
-
一个类中可以定义多个构造器,但是构造器的参数列表必须不同(重载)
-
如果我们没有手动定义构造器,则Java系统会提供一个默认的构造器给我们使用,一旦我们定义了构造器,则系统会把默认的构造器收回
-
构造器的作用:实例化对象,给对象赋初始值
-
代码游离块优先执行
这是写构造器时需要注意的事项,接下来一一讲解
为啥要写构造器?写来有啥用?可不可以不写?
构造器用来实例化对象,可以不写,每一个类都有一个默认的且隐身的无参构造方法,意思就是你不写,它也有。
但是一旦你写了,这个默认的隐身的就没了。
构造器也叫构造方法,也是一种方法,可以根据需要写多个,用来实现不同功能。
在Java里,所有东西都需要被初始化才能使用,一下举例
int a1;//未初始化,不会报错,但使用范围被局限
int a2 = 0;
String b1;//未初始化,不会报错,但使用范围被局限
String b2 = "";
double[] d1;//未初始化,不会报错,但使用范围被局限
double[] d2 = [0.12, 23.54];
上面代码块中后面有注释的那些,容易在编译时出现红色的报错(说个笑话,我不在乎警告,只要没有异常,错误不是我的)
因为变量在声明的时候,需要声明类型、声明名字、初始化,哪怕初始化一个空(null的读音,10个程序员有20种读法,我是已经放弃标准发音了)的值,也都是可以的。
对象也是一样的,在新建对象的时候,构造器的作用就有初始化这一个过程,只不过看不到罢了。
看一下下面这个案例
public class Point {
private int x;
private int y;
public Point() {
}
public Point(int x, int y) {
this.x = x;
this.y = y;
}
@Override
public String toString() {
return "Point{" + "x=" + x + ", y=" + y + "}";
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Point point = (Point) o;
return x == point.x && y == point.y;
}
@Override
public int hashCode() {
return Objects.hash(x, y);
}
public int getX() {
return x;
}
public void setX(int x) {
this.x = x;
}
public int getY() {
return y;
}
public void setY(int y) {
this.y = y;
}
}
这是一个标准的JavaBean,一个标准的JavaBean至少拥有
-
一个无参的构造器
-
一个有参的构造器
-
getter和setter方法
其中的toString()、equals()、hashCode()能看见有个@Override的注释,这是重写,重写和重载后面有缘再讲哈哈哈,玩的就是一个缘分。
之所以要写这么一个类,是为了在其它类中实例化并运用它,来体现构造器的作用,对象的作用。
public class ObjectDemo {
public static void main(String[] args) {
Point p = new Point(100,200);
System.out.println(p);
System.out.println(p.toString());
Point p1 =new Point(100,200);
Point p2 =new Point(100,200);
System.out.println(p1==p2);//false
System.out.println(p1.equals(p2));//重写过后为true
}
}
输出为
Point{x=100, y=200}
Point{x=100, y=200}
false
true
如果上面不重载那三个方法的话,输出的是。
object.Point@232204a1
object.Point@232204a1
false
false
232204a1就是地址啦,16进制的哇。
这不是我们要的东西,所以要重载,怎么重载看缘分...
回到第二个代码块
Point p = new Point(100,200);
这就是在另外一个类创建了一个同一个包中的这个类的对象。
说的仔细一点就是在ObjectDemo类中实例化并初始化了一个叫p的Point对象,传入参数为100,200。
说的白话一点就是,new了一个点p,坐标为(100,200)。
若我们需要不同的点,就可以不断的来new对象来获得不同的点,不用担心占用过多内存,每个对象在被用完后就被回收了。
当然也可以不传参,不传参的情况下,x=0,y=0,
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Point point = (Point) o;
return x == point.x && y == point.y;
}
这是因为重写了这个equals方法,所以在初始化的时候,若x==null,y==null时,就自动赋值为0,这样更符合实际功能需求
所以,总结一下,构造器就是一个类被实例化的必要条件,多个构造器需要不同的参数列表,在实例化时,根据传入参数自动选择不同的构造器。
哦对了,对象的存在是为了某个东西的复用,构造器是对象(万物皆是对象)实例化的前提。