我有三个这样的课程:
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会在编译期间插入它,因为这个类中没有其他构造函数,对吧?
如果为true,我可以将ClassC
的代码简化为:
public abstract class ClassC extends ClassB {
// more code
}
现在我要说ClassB
我不能这样做,因为构造函数的可访问性从protected
增加到public
。
我问,因为我不是100%肯定这一点,并认为我可能会遗漏一些东西。特别是关于如果我自己不实现它将插入ClassC
的标准构造函数。在这种情况下,它将具有辅助功能public
,因为它继承自ClassB
。这是对的吗?
所以我的问题是:我可以删除ClassC中的构造函数而不更改代码(尤其是构造函数的可访问性),并且我无法删除ClassB的构造函数。
答案 0 :(得分:3)
现在我要说我不能对ClassB做同样的事情,因为构造函数的可访问性从protected变为public。
这是无关紧要的,因为它是一个抽象类。无法直接调用构造函数 - 它仅在从子类构造函数链接时使用。
因此,虽然它在技术上不同,但如果删除了所有构造函数声明,则代码将有效。
但就默认构造函数的可访问性而言,JLS 8.8.9是这里的权限:
如果类不包含构造函数声明,则隐式声明默认构造函数。顶级类,成员类或本地类的默认构造函数的形式如下:
- 默认构造函数与类具有相同的可访问性(第6.6节)。
- ...
答案 1 :(得分:1)
类的默认构造函数具有与类本身相同的访问修饰符的规则简单直观。但请注意,这并不意味着只要可以访问类,就可以访问构造函数。
这意味着如果您的构造函数在子类的范围内定义,则无需显式调用
super()
。在您的情况下,您可以删除所有构造函数。您的程序仍将编译并运行。
希望这会有所帮助。有关更多信息,请查看共享链接,它有一些更漂亮的示例。
答案 2 :(得分:0)
来自Java specification on default constructor。
如果类不包含构造函数声明,则隐式声明没有形式参数且没有throws子句的默认构造函数。
如果声明的类是原始类Object,则默认构造函数具有空体。否则,默认构造函数只调用不带参数的超类构造函数。
所以你应该善于不包括任何这些构造。