是否需要编写默认构造函数?
Posted
技术标签:
【中文标题】是否需要编写默认构造函数?【英文标题】:Is writing a default constructor necessary? 【发布时间】:2017-07-15 23:01:33 【问题描述】:我正在尝试为扩展超类Account
的子类SavingsAccount
编写构造函数。 Account 已经有一个带有两个参数(id
和balance
)的构造函数。 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 是唯一的超类,没有问题。
【讨论】:
以上是关于是否需要编写默认构造函数?的主要内容,如果未能解决你的问题,请参考以下文章