1 作用和特点
1.1 作用
给对象中的成员进行初始化。
1.2 特点
- 方法名与类名相同;
- 没有返回值类型,连void都没有;
2 注意事项
- 如果没有给出构造方法,系统将自动提供一个无参构造方法;
- 如果给出了构造方法,系统将不再提供默认的无参构造方法,这时如果还想使用无参构造方法,就必须自己给出,建议永远给出无参构造方法;
- 因为当父类存在有参构造时,子类构造不会自动调用父类有参构造,仍然默认调用super()即父类无参构造,如果父类没有自己给出无参构造,就会报错;
3 加载机制
- 当通过子类的构造方法来实例化一个子类时,该构造方法会首先调用直接父类的构造方法,而父类的构造方法也会调用其直接父类的构造方法;
- 这个过程不断重复,直到到达了java.lang.Object类的构造方法,即子类的所有父类也会被实例化;
4 案例
4.1 隐式/显式调用父类无参构造
public class Base {
public Base(){
System.out.println("Base 的无参数的构造函数被调用");
}
public Base(String str){
System.out.println("Base 的带一个参数的构造函数被调用"+"--"+str);
}
}
public class Sub extends Base{
public Sub(){
// super();
System.out.println("Sub 的无参数的构造函数被调用");
}
public Sub(String str){
System.out.println("Sub 的带一个参数的构造函数被调用");
}
public static void main(String[] args) {
Sub sub=new Sub();
}
}
Base 的无参数的构造函数被调用
Sub 的无参数的构造函数被调用
4.2 显式调用父类有参构造
class Base {
public Base(){
System.out.println("Base 的无参数的构造函数被调用");
}
public Base(String str){
System.out.println("Base 的带一个参数的构造函数被调用"+"--"+str);
}
}
public class Sub extends Base{
public Sub(){
super("Java");
System.out.println("Sub 的无参数的构造函数被调用");
}
public Sub(String str){
System.out.println("Sub 的带一个参数的构造函数被调用");
}
public static void main(String[] args) {
Sub sub=new Sub();
}
}
Base 的带一个参数的构造函数被调用--Java
Sub 的无参数的构造函数被调用
4.3 父类有有参构造,无无参构造
class Base {
public Base(String str){
System.out.println("Base 的带一个参数的构造函数被调用"+"--"+str);
}
}
public class Sub extends Base{
public Sub(){
System.out.println("Sub 的无参数的构造函数被调用");
}
public Sub(String str){
System.out.println("Sub 的带一个参数的构造函数被调用");
}
public static void main(String[] args) {
Sub sub=new Sub();
}
}
There is no default constructor available in 'Base':9
There is no default constructor available in 'Base':13
- 此时子类的两个构造方法都报错了,因为子类没有显式调用父类含参构造方法,将默认调用父类无参构造,然而父类因为定义了一个有参构造,就不会再隐式添加无参构造了,因此报错;
- 解决问题的方法有两个,要么为父类显式添加一个无参构造函数,要么使子类的构造函数显式调用父类的有参构造函数;