在这种情况下是不是需要实现标准构造函数(Java)?
Posted
技术标签:
【中文标题】在这种情况下是不是需要实现标准构造函数(Java)?【英文标题】:Is implementation of a standard constructor (Java) necessary in this case?在这种情况下是否需要实现标准构造函数(Java)? 【发布时间】:2015-10-19 00:16:43 【问题描述】:我有三个这样的课程:
public abstract class ClassA extends ClassX
protected ClassA()
super();
// more code
public class ClassB extends ClassA
public ClassB()
super();
// more code
public abstract class ClassC extends ClassB
public ClassC()
super();
// more code
我想说ClassC
的标准构造函数不是必需的,因为Java 会在编译期间插入它,因为此类中没有其他构造函数,对吧?
如果属实,我可以将ClassC
的代码简化为:
public abstract class ClassC extends ClassB
// more code
现在我想说我不能对ClassB
做同样的事情,因为构造函数的可访问性从protected
增加到public
。
我之所以这么问,是因为我对此不是 100% 确定,并认为我可能会遗漏一些东西。特别是关于将插入ClassC
的标准构造函数,如果我自己不实现它。在这种情况下,它将具有可访问性 public
,因为它继承自 ClassB
。对吗?
所以我的问题是:我可以在不更改代码的情况下删除 ClassC 中的构造函数(尤其是构造函数的可访问性)吗?我不能删除 ClassB 的构造函数是否正确。
【问题讨论】:
您可能应该提出单独的问题 :) 长话短说。你的假设似乎是正确的 你是对的 :-)。所以我的问题主要是:我可以在不更改代码的情况下删除 ClassC 中的构造函数吗(将编辑问题)。 我不确定你的意思是什么: > 现在我想说我不能对 ClassB 做同样的事情,因为构造函数的可访问性从受保护增加到公共。默认构造函数是包私有的。 @RazvanManolescu:如果默认构造函数是包私有的,那意味着,如果我删除 ClassC 的构造函数,java 将不会添加默认构造函数,因为它不能具有较低的可访问性(包私有),或者它将添加一个不是包私有而是公共的构造函数(因为它必须等于或高于它的父级)。你会说Java插入哪一个? 【参考方案1】:现在我想说我不能对 ClassB 做同样的事情,因为构造函数的可访问性从受保护增加到公共。
这无关紧要,因为它是一个抽象类。不能直接调用构造函数 - 它仅在从子类构造函数链接时使用。
因此,虽然技术上会有所不同,但如果您删除所有构造函数声明,您的代码将实际上相同。
但就默认构造函数的可访问性而言,JLS 8.8.9 是这里的权威:
如果类不包含构造函数声明,则隐式声明默认构造函数。***类、成员类或本地类的默认构造函数形式如下:
默认构造函数具有与类相同的可访问性(第 6.6 节)。 ...
【讨论】:
"默认构造函数与类具有相同的可访问性" --> 很有帮助,非常感谢! 我的困惑是因为我认为默认构造函数继承了其父类的无参数、无抛出语句构造函数的可访问性。由于文档说它继承了类本身的可访问性,现在很清楚了。 关于 ClassA 是抽象的好评论 - 你是对的,那么我也可以删除那里的构造函数。想知道是谁把它放在那里的:-)【参考方案2】:类的默认构造函数与类本身具有相同的访问修饰符的规则简单直观。但是请注意,这并不意味着只要类可访问,就可以访问构造函数。
-
如果你不创建构造函数,default empty constructor is automatically created。
如果任何构造函数没有显式调用 super 或 this 构造函数作为其第一条语句,则为 call to super() is automatically added。
这意味着如果您的构造函数是在子类的范围内定义的,则无需显式调用
super()
。与您的情况一样,您可以删除所有构造函数。您的程序仍将编译并运行。
希望这会有所帮助。有关更多信息,请查看共享链接,其中有一些更漂亮的示例。
【讨论】:
【参考方案3】:来自Java specification on default constructor。
如果一个类不包含构造函数声明,则隐式声明一个没有形式参数且没有 throws 子句的默认构造函数。
如果声明的类是原始类 Object,则默认构造函数的主体为空。否则,默认构造函数只会调用不带参数的超类构造函数。
所以你应该很好地不包括任何这些构造函数。
【讨论】:
以上是关于在这种情况下是不是需要实现标准构造函数(Java)?的主要内容,如果未能解决你的问题,请参考以下文章