我们在定义一个类的时候,如果需要重新写一个构造函数,就必须要写一个无参构造函数,如下代码所示,那这到底是为什么?
public class Fruit { private String name; // 必须显式声明一个无参构造函数 public Fruit(){} public Fruit(String name){ this.name = name; } public String getName() { return name; } public void setName(String name) { this.name = name; } }
要回答这个问题,我们就来把这个无参构造函数去掉试试。
按照如下方式,用起来也没多大的问题:
public static void main(String[] args){ Fruit apple = new Fruit("apple"); // print "apple" System.out.println(apple.getName()); }
但是,当我们需要派生一个子类的时候,编译就报错了:
public class Apple extends Fruit { // There is no default constructor available in 'cn.zx.demo.Fruit' }
这是因为,子类在使用自己的默认无参构造函数初始化的时候,会执行super()来调用父类的默认无参构造函数,但是父类中此时没有这样的构造函数,因此编译器认为出现了异常。
如果我们在父类Fruit中显式地声明一个无参构造函数,就像本文一开始演示的代码一样,那么就不会出现这样的问题了。
再进一步思考,如果子类实例化的时候不使用super()来调用父类的无参构造函数是不是就不会出现这样的问题了呢?
答案是肯定的:
public class Apple extends Fruit { public Apple(String name){ super(name); } }
只要在子类中指定调用父类中存在的构造函数,那么子类就是可以被正确初始化的,程序编译也就没有问题。
然而,我们其实并不能确定将要如何初始化一个子类,而且,我们也不可能为每一个子类都显式地调用其存在的父类构造函数,这样太过繁琐。
比如,我们需要创建一个没有name属性的banana对象,那么此时将没有合适的父类的构造方法供调用:
public class Banana extends Fruit { public Banana (){ // 没有合适的父类构造函数供调用 } }
所以,为了可扩展,在类中重新写构造函数的时候,额外声明一个无参构造函数是一个良好的编程习惯。
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------
以上都是转载,内容也很好理解,但是今天看业务代码,无参构造函数是私有的,private修饰的。这就很令人费解了,查了一下,应该是基于以下原因: