概念
- 构造方法会在对像创建是被自动调用
- 构造方法又叫工厂函数,它可以在类实例化对象之初对对象的成员属性的值进行初始化,对成员方法进行初始化调用
绪论
- 一般来说,如果我们希望给类指定一个成员变量,我们可以直接在创建类的时候给成员变量一个初始值
java
public class Bus {
int width;
int height;
int seating;
double price = 2.0;
//这里我将price的初始值设置为2.0,这样每次创建类,该成员变量就会被设置为2
double balance;
String number;
boolean isOpen;
boolean isRuning;
public Bus(){
price = 2;
regist("A888888");
}
public void stop() {
isRuning = false;
System.out.println("已停车!");
}
public void start() {
isRuning = true;
System.out.println("正在行驶!");
}
public void regist(String no) {
number = no;
System.out.println("注册成功!您的车牌号是" + number);
}
...
}
- 还可这样做,在创建之初就调用setPrice方法
java
//还可以这样做
public class Bus {
int width;
int height;
int seating;
double price = setPrice();
//这里在创建之初就会调用sePrice方法,返回一个double值,给成员变量price设置初始值
double balance;
String number;
boolean isOpen;
boolean isRuning;
public double setPrice(){
return 2.0;
}
public void stop() {
isRuning = false;
System.out.println("已停车!");
}
public void start() {
isRuning = true;
System.out.println("正在行驶!");
}
public void regist(String no) {
number = no;
System.out.println("注册成功!您的车牌号是" + number);
}
...
}
- 实际上我们使用构造方法也可以实现类似的效果
创建方式
- 在类中创建公开(public)且和类名相同的方法
- 如下方代码所示方法Bus和类同名,且修饰符为public那么此方法就为bus的构造方法,这个构造方法会在Bus类的对象创建之初,初始化成员变量price和number的值
java
public class Bus {
int width;
int height;
int seating;
double price;
// double price = setPrice;
double balance;
String number;
boolean isOpen;
boolean isRuning;
/* public double setPrice(){
return 2.0; }*/
public Bus(){
price = 2;
regist("A888888");
}
public void regist(String no) {
number = no;
System.out.println("注册成功!您的车牌号是" + number);
}
}
构造方法的巧用
- 构造方法除了上述给,还可以指定用户在调用时候需要传入指定的默认值,才可创建对象
- 比如公交公司的管理系统中,一辆公交车,没有牌照就一定是违法的,不能上路(创建为象),但牌照需要摇号在才能确定,但我们指定牌照属性的默认值只能指定一个牌照,不同公交车不能有同一个牌照,那么我们就可以在构造方法中要求用户先办理牌照才可以上路(创建对象)。
java
public class Bus {
double price;
double balance;
String number;
public Bus(String n){
price = 2;
regist(n);
}
public void regist(String no) {
number = no;
System.out.println("注册成功!您的车牌号是" + number);
}
public void pay(double money) {
if (money < price) {
System.out.println("钱没给够,快下车!");
} else {
balance = balance + money;
seating -= 1;
System.out.println("欢迎乘坐!");
}
}
}
我们在创建Bus类的时候则必须传一个参数否则会报错
java
public class demo {
public static void main(String[] args) {
Bus b = new Bus("A000000"); //创建对象需要传参
// b.regist("闽A000000");
Bus b1 = new Bus("A0000002");
// b1.regist("闽A000000");
b1.pay(2);
Bus b2 = new Bus("A000003");
// b2.regist("闽A000000");
b2.pay(0);
}
}
构造方法的重载
- 面对不同的情况我们可以创建不同的构造方法,java会更具我们传入的参数,自动帮我们选择构造方法,如下方代码所示,创建了一个空构造方法。
java
public class Bus {
double price;
double balance;
String number;
public Bus(){
}
public Bus(String n){
price = 2;
regist(n);
}
public void regist(String no) {
number = no;
System.out.println("注册成功!您的车牌号是" + number);
}
public void pay(double money) {
if (money < price) {
System.out.println("钱没给够,快下车!");
} else {
balance = balance + money;
seating -= 1;
System.out.println("欢迎乘坐!");
}
}
}
这时候即使我们创建对象没有传入参数也不会报错,因为java帮我们自动匹配了没有参数的构造方法
java
public class demo {
public static void main(String[] args) {
Bus b = new Bus(); //自动选在了没有参数的构造方法
Bus b1 = new Bus("A0000002"); //自动选择了有参数的构造方法
b1.pay(2);
}
}
- 还有一种比较有意思的写法
java
public class Bus {
double price;
double balance;
String number;
public Bus(){
this("A666666"); //这里相当于向Bus类的构造函数Bus中传入了"A666666"
} //这里表达的逻辑是,如果没有传入参数,那就初始化为"A666666"
public Bus(String n){
price = 2;
regist(n);
}
public void regist(String no) {
number = no;
System.out.println("注册成功!您的车牌号是" + number);
}
public void pay(double money) {
if (money < price) {
System.out.println("钱没给够,快下车!");
} else {
balance = balance + money;
seating -= 1;
System.out.println("欢迎乘坐!");
}
}
}
当我们使用new Bus()语句创建对象的时候,我们创建对象中车牌属性number会初始化为"A666666",因为当我们使用new Bus()创建对象的途中,先是调用了没有参数的构造函数bus(),这个构造函数中有一个this(),且传入了一个参数"A666666",this指定是当前调用该函数的对象,这里的this("A666666")就相当于new Bus("A666666"),java编译器又自动将这个对象匹配给有参数的构造函数bus(String),所以车牌就这样被初始化了,我们按住键盘ctrl会发现,会跳转到有参数的构造函数bus(String)
java
public class demo {
public static void main(String[] args) {
Bus b = new Bus();
//自动选在了没有参数的构造方法,当this("A666666"),调用了有参数的构造方法
Bus b1 = new Bus("A0000002"); //自动选择了有参数的构造方法
//b1.regist("A000000");
b1.pay(2);
System.out.println(b.number);//A666666
}