目录
一、构造方法
1.从方法到构造方法
今天我们来讲讲什么是构造方法,不同于千篇一律一上来就给出定义(形如...的是构造方法),先进行一些回顾,从我们更为熟悉的“方法”下手。
那么,什么是方法?
这应该是学习Java第一节课入门时就已经了解了的一个名词。方法是一种函数,也是一个代码片段,用于执行特定的任务或操作,或者可以说是一段封装了特定功能或任务的可重用代码块。
方法有哪些种类呢?
除了我们经常接触的实例方法(也称成员方法),比较陌生的静态方法,还有就是我们今天要讲的构造方法了。抽象方法目前用到的比较少,暂且不做提及。
其实,构造方法与实例方法大有不同,下面我们就来看看到底什么是构造方法。
2.什么是构造方法
1)构造方法的定义
长成如下这种样子的我们就叫做构造方法:
→ 无返回值(含void)、方法名与类名相同,在创建对象时由编译器自动调用
public class( ){
}
在每个类中都自带构造方法,但该构造方法无参数及方法内容。我们也可以自己在类中创建构造方法。每个类都有至少一个构造方法,如果没有明确定义,Java会提供一个默认的无参构造方法。
证明如下:创建一个名为空的类和一个主函数后,在out里我们寻找相对应的文件名打开。
会得到如下的结果
2)构造方法的作用
构造方法是一种特殊的方法,它的作用是在创建对象时初始化对象的状态。
通过构造方法,我们可以在创建对象时为对象的属性赋初值。
使用构造方法时可以将赋值的代码写好,在之后主函数入口创建对象时就不需要使用对象变量名一个一个赋值了,可以直接按照在构造方法中“打包”的格式在主函数中直接创建对象后传入值(可以在下面的代码实例中具体理解)。
——总结一下就是构造方法通常用于初始化和代码复用。
3.构造方法的代码实例
1) 系统默认的无参构造方法
虽然代码中没有明确定义构造方法,但默认构造方法确实存在并被调用。
在主函数中Data实例化对象时,会调用默认构造方法来初始化对象。
public class Data {
private int age;
private String name;
private boolean gender;
public void printInfo(){
System.out.println("age"+age+"name"+name+"gender"+gender);
}
public static void main(String[] args){
Data data = new Data();
data.printInfo();
}
}
输出结果:0+null+false
2) 在1.0的基础上为成员属性进行赋值
public class Data {
private int age=1;
private String name="abc";
private boolean gender=true;
public void printInfo(){
System.out.println("age:————"+age+" name:————"+name+" gender:————"+gender);
}
public static void main(String[] args){
Data data = new Data();
data.printInfo();
}
}
输出结果:age:————1 name:————abc gender:————true
3) 定义一个带有参数的构造方法
在主方法中,实例化Data对象时调用了新定义的带参数的构造方法,传入具体的参数值来初始化对象。
public class Data {
private int age;
private String name;
private boolean gender;
public Data(int age,String name,boolean gender){
this.age=age;
this.name=name;
this.gender=gender;
System.out.println("调用一次构造方法");
}
public void printInfo(){
System.out.println("age:————"+age+" name:————"+name+" gender:————"+gender);
}
public static void main(String[] args){
Data data = new Data(1,"abc",true);
data.printInfo();
}
}
输出结果:age:————1 name:————abc gender:————true
看到这里,我们不妨思考一下,从1.0过渡到3.0中,究竟有哪些差异,或者说是我们定义的构造函数体现了什么样的作用。
1.0是我提供的一个最基本的代码,2.0在此基础上对私有变量进行了赋值,3.0虽然与2.0是同样的输出结果,但多出了一块构造方法,以及在创建(实例化)对象时也是略有差异。
4.分析代码与总结
1)this关键字的一些作用
作用 | 区分局部变量和实例变量 | 当方法的参数或局部变量与实例变量同名时,使用 this 可以明确指示要操作的是实例变量。 |
在构造方法中调用其他构造方法 | 在构造方法中使用 this(...) 可以调用同一个类中的其他构造方法。这样可以避免重复代码,并实现代码的复用。 例如,this(year, month, day) 可以在构造方法中调用另一个构造方法来初始化对象。 |
this.实例变量=构造方法中的参数值;
参数变量可以接收外部传入的数值,将值赋给当前类的实例变量,从而初始化对象的状态。
2)构造方法和一般方法的区别
从上述给出的代码不难看出,一般方法都需要我们在主函数中先创建对象然后利用对象调用方法,构造方法则不需要我们调用由Java编译器自动调用。
二、方法重载
1.什么是方法重载?
定义:方法重载机制允许一个类中存在多个重名方法,但必须要求参数数量、(当数量一致)参数类型、(当数量类型一致)顺序不一致。
参数数量→ |
|
|
参数类型→ |
| |
| →参数顺序 |
在上述JButton中我们可以选择在按钮上放字符串或者是图标Image就体现了方法重载机制。
从方法重载不难推出构造方法也可以重载,从而一个类可以定义多个构造方法。
2.方法重载的代码实例
public class Car {
private String brand;
private String model;
private int year;
// 无参构造方法
public Car() {
this.brand = "Unknown";
this.model = "Unknown";
this.year = 0;
}
// 带参数的构造方法
public Car(String brand, String model, int year) {
this.brand = brand;
this.model = model;
this.year = year;
}
public void displayInfo() {
System.out.println("Car brand: " + brand);
System.out.println("Car model: " + model);
System.out.println("Car year: " + year);
}
public static void main(String[] args) {
Car car1 = new Car(); // 调用无参构造方法
car1.displayInfo();
Car car2 = new Car("Toyota", "Camry", 2022); // 调用带参数的构造方法
car2.displayInfo();
}
}
三、整体代码(构造方法+方法重载)
import java.util.concurrent.ThreadLocalRandom;
public class Data {
private int age;
private String name;
private boolean gender;
private long ID;
public Data(){
this(10,"111",true);
}
/**
* true:男
* false:女
*/
public Data(int age,String name,boolean gender){
this.age=age;
this.name=name;
this.gender=gender;
System.out.println("---------------------------");
randomID();//可以不需要在主函数处调用两次
printInfo();
//System.out.println("调用一次构造方法");
System.out.println("---------------------------");
}
public void printInfo(){
System.out.println("age:"+age+"\nname:"+name+"\ngender:"+gender);
}
public void randomID(){
ID= ThreadLocalRandom.current().nextLong();
System.out.println("ID:"+ID);
}
public static void main(String[] args){
Data data1 = new Data(1,"abc",true);//分别会输出一次“调用一次xxxx”
Data data2 = new Data(2,"www",false);
//Data data = new Data();
}
}
从代码运行结果不难看出两个data对象分别调用了一次构造方法,总计两次。
略有不同的是,我将所有方法的初始化都放在了构造方法中(在构造方法中调用了实例方法),所以主函数入口中看起来略显单薄,这样优点确实代码更加简便一点,但同时也包含一些隐藏的缺点(如对象未完全初始化完成的情况下就提前输出信息等等)。
在未来会做进一步的研究与讨论,如有提议可在评论区提出。