Oracle Java教程网站的这一段令我感到困惑:
所有课程至少有一个 构造函数。如果一个课没有 显式声明任何,Java 编译器自动提供 无参数构造函数,称为 默认构造函数。这个默认值 构造函数调用类父类 无参数构造函数或Object 如果类没有其他的构造函数 家长。如果父母没有 构造函数(Object确实有一个), 编译器将拒绝该程序。
如果所有对象直接或间接地从Object继承,那么如何引出编译器拒绝?是否与私有的构造函数有关?
答案 0 :(得分:31)
如果所有对象直接或间接地从Object继承,那么如何引出编译器拒绝?
我认为你误解的基础是你思考构造函数是继承的。实际上,构造函数不是用Java继承的。请考虑以下示例:
public class A {
public A(int i) { super(); ... }
}
public class B extends A {
public B() { super(); ... }
}
班级A
:
Object
,public A() {...}
)和因此,它只有一个构造函数:public A(int)
。
super()
类中对B
的调用尝试在A
中使用不存在的无参数构造函数,并给出编译错误。要解决此问题,您需要更改B
构造函数以使用A(int)
构造函数,或在A
中声明显式的no-args构造函数。
(顺便说一句,构造函数没有必要显式地调用超类构造函数......就像我已经完成的那样。但是很多人认为包含显式调用是好的风格如果省略,Java编译器会对超类no-args构造函数插入一个隐式调用...如果no-args构造函数不存在或子类不可见,则会导致编译错误。)< / p>
是否与私有的构造函数有关?
不直接。但是,声明构造函数private将阻止从子类调用该构造函数。
答案 1 :(得分:15)
要理解的关键是,如果类还没有构造函数,那么no-arg构造函数将仅自动生成。
因此很容易创建一个没有no-arg构造函数的类。
答案 2 :(得分:9)
想到这个问题的最简单方法如下:
非args构造函数由Java为您创建的任何类提供为默认构造函数。
当您使用参数创建自定义构造函数时,Java会说“嘿,这个类有一个自定义构造函数,所以我不打算创建/提供默认的非args构造函数!” /强>”
结果现在你的类没有默认的非args构造函数。
这意味着当您根据类创建子类时,需要显式调用您创建的基于自定义构造函数的参数。
答案 3 :(得分:4)
如果你有一个子类的子类
class A
{
A(int i) {..}
}
class B extends A
{
}
这里插入B
的默认构造函数将尝试调用A的无参构造函数(它不存在),因为它只有一个构造函数接受一个参数
答案 4 :(得分:1)
对象的 immediate 超类必须具有受保护或公共构造函数(或者根本没有构造函数,在这种情况下将创建一个)。因此,如果我创建一个扩展Object的类,只使用私有构造函数,那么任何东西都无法扩展我的类。
答案 5 :(得分:1)
是。私有构造函数是一个特殊的实例构造函数。它通常用于仅包含静态成员的类中。如果一个类有一个或多个私有构造函数而没有公共构造函数,则不允许其他类(嵌套类除外)创建此类的实例。
私有构造函数的声明会阻止自动生成默认构造函数。
编辑:
在另一个类中定义的类 被称为嵌套类。像其他人一样 一个类的成员,一个嵌套类可以 被宣布为静态。一个 非静态嵌套类称为 内心阶级。 内心的一个例子 class只能存在于一个中 封闭类的实例和 可以访问其封闭类 成员,即使他们被宣布 私人强>
答案 6 :(得分:0)
这意味着如果你继承了一行使默认的no-arg构造函数为private(或者它不存在,例如)的类,你的子类必须声明一个符合的构造函数它的父母的替代构造函数。
例如,不允许使用以下Bar条声明:
public class Foo {
private Foo() { } // or this doesn't even exist
public Foo(int i) {
}
}
public class Bar extends Foo {
}
答案 7 :(得分:0)
让我附上所有上述一个有趣的案例,其中default / no-arg构造函数是不可行的,除非它是显式声明的,否则编译器不能假设它,但它与子类没有任何关系。这是一个具有final
字段的类的情况,该字段需要构造函数初始化它。例如:
class Foo extends Object {
private final Object o;
public Foo(Object o){
this.o = o;
}
}
这里很容易看到Foo对象的实例化需要初始化最终字段o
,因此任何Foo()
的调用 - 无论是否直接 - 都注定要失败......我强调超类(Object
)中的无参数构造函数存在且可公开访问,但最终字段(o
)的存在会在Foo
中停用它。