Java类继承时是否必须手动调用父类构造函数?能否自动触发?
Java继承中父类构造函数的调用问题
问题1:继承类时是否必须每次手动调用super来触发父类构造函数?
这得分情况来看:
- 如果你的父类存在无参构造函数(不管是你显式定义的,还是Java默认生成的——当类没有任何构造函数时,Java会自动提供一个无参构造),那么子类的构造函数会自动隐式调用父类的无参构造,这种情况下你完全不用手动写
super()。 - 但如果你的父类只有带参数的构造函数(就像你提供的
TestSet类,只有TestSet(String name)这一个构造),Java没办法自动帮你调用父类构造——因为它不知道该传什么参数进去。这种情况下,子类的每个构造函数都必须显式调用super(参数),否则编译器会直接报错。
拿你的例子来说,TestSet只有带String参数的构造,所以TC1SendAnEmail必须手动写super("某个名称"),不然编译根本通不过。
问题2:有没有办法在继承时自动触发父类构造函数?
Java本身没有办法完全“自动”让子类不用写任何代码就触发带参数的父类构造,但可以通过一些变通方案来减少重复代码:
方案1:给父类添加一个无参构造函数
你可以给TestSet加一个无参构造,给name设一个默认值,这样子类构造时会自动调用这个无参构造,不用手动写super:
public class TestSet { // 新增无参构造,带默认名称 public TestSet() { Logger.msg("Test set: Default Test Set"); } public TestSet(String name) { Logger.msg("Test set: " + name); } }
这样子类TC1SendAnEmail即使不写任何构造函数,Java会自动给它生成一个无参构造,并且隐式调用父类的无参构造,触发日志输出。如果需要指定自定义名称,还是可以手动调用super("自定义名称")。
方案2:让子类构造函数统一调用父类构造
如果必须保留父类只有带参构造的情况,你可以在子类中定义构造函数时,要么直接传递参数给父类,要么给子类构造设置默认参数:
public class TC1SendAnEmail extends TestSet{ // 子类无参构造,自动传递默认名称给父类 public TC1SendAnEmail() { super("TC1 Send An Email"); } // 如果需要自定义名称,提供带参构造 public TC1SendAnEmail(String name) { super(name); } }
这样后续子类只需要根据需求选择调用哪个构造,不用每次都重复写super的逻辑。
方案3:使用工厂模式创建子类实例
如果想彻底避免子类中写构造函数的重复代码,可以用工厂类来统一创建子类实例,在工厂方法中处理父类构造的调用:
public class TestSetFactory { public static <T extends TestSet> T createTestSet(Class<T> clazz, String name) throws Exception { // 通过反射创建子类实例,同时传递name给父类构造 return clazz.getConstructor(String.class).newInstance(name); } }
使用时直接调用TestSetFactory.createTestSet(TC1SendAnEmail.class, "TC1 Send An Email"),这样子类本身不用处理super的调用,统一由工厂负责。
内容的提问来源于stack exchange,提问作者Jan Kl.
相关产品推荐
相关产品推荐

