是否需要编写默认构造函数?

Posted

技术标签:

【中文标题】是否需要编写默认构造函数?【英文标题】:Is writing a default constructor necessary? 【发布时间】:2017-07-15 23:01:33 【问题描述】:

我正在尝试为扩展超类Account 的子类SavingsAccount 编写构造函数。 Account 已经有一个带有两个参数(idbalance)的构造函数。 SavingsAccount 的构造函数与 Account 的构造函数非常相似,只是我需要以不同的方式验证 balance,因此我不想将 super(String id, int balance) 用于构造函数。

当我尝试创建一个新的构造函数时,我的 IDE 告诉我“'Account' 中没有可用的默认构造函数”。我不明白为什么当我在 SavingsAccount 中编写新构造函数时它告诉我需要一个默认构造函数。

我真的需要编写一个默认构造函数吗?还是我当前的构造函数中有些东西不太正确?

超类:

public class Account extends Bank 

String id;
int balance;

Account(String id, int balance)

    if(balance < 0)
        throw new IllegalArgumentException("Balance cannot be less than 0.00");

    this.id = id;
    this.balance = balance;

和子类:

public class SavingsAccount extends Account 

String id;
int balance;

SavingsAccount(String id, int balance)
    if(balance < 1000)
        throw new IllegalArgumentException("Balance cannot be less than 10.00");

    this.id = id;
    this.balance = balance;

【问题讨论】:

问题是如果不调用super,Java会隐式调用,不带参数。由于你的超类没有没有参数的构造函数,所以它不会工作...... 您的SavingsAccount 类有两个不同的 id 字段和两个不同的 balance 字段。这几乎肯定不是你想要的。 如果您不提供构造函数,编译器将为您创建一个不带参数的构造函数(并调用不带参数的超类构造函数)。但是它不起作用,因为您的超类已经包含一个非空构造函数(因此编译器不会为您创建一个)。简而言之,您需要创建一个适当的构造函数来调用适当的超类构造函数(如 Elliott 的回答所示)。 关于您的模型和继承的旁注:Account extends Bank 听起来不太对劲。确定是否应该使用继承的常用方法是“is-a”测试;一个帐户不是银行,但银行 1...n 个帐户。因此,请考虑修改您的模型并在顶层使用 组合而不是继承 另一个注意事项:根据定义,您不能编写默认构造函数。默认构造函数是类源代码中没有构造函数时编译器提供的构造函数。 【参考方案1】:

构造函数的第一行需要调用适当的超级构造函数。加super(id, balance);

SavingsAccount(String id, int balance)
    super(id, balance);

这将验证balance 是否大于0,然后验证balance 是否大于10。或者,将一个空构造函数添加到 Account

Account() 

这将使您的子类能够实例化(因为编译器插入了对super() 的空调用)。注意这是一个空的构造函数,只有在你没有定义任何构造函数的情况下才会添加默认构造函数。

【讨论】:

哦,我明白了。我没有意识到超级构造函数是必要的。解决方案完美运行。谢谢。【参考方案2】:

仅供参考,此取自from the java docs from Oracle

注意:如果构造函数没有显式调用超类构造函数,Java 编译器会自动插入对超类的无参数构造函数的调用。如果超类没有无参数构造函数,则会出现编译时错误。 Object 确实有这样的构造函数,所以如果 Object 是唯一的超类,没有问题。

【讨论】:

以上是关于是否需要编写默认构造函数?的主要内容,如果未能解决你的问题,请参考以下文章

超类是不是需要默认构造函数? [复制]

为啥并不总是有默认构造函数[重复]

类型是不是需要默认构造函数才能声明它的数组?

如果类成员是向量,我们是不是应该显式编写复制构造函数?

关于复制构造函数的几个问题

子类构造函数是否会默认调用父类的无参构造函数