为什么不能this()
和super()
两者在构造函数中一起使用?
加入这样一个东西的原因是什么?
this(...)
将调用同一个类中的另一个构造函数,而super()
将调用一个超级构造函数。如果super()
构造函数中没有,编译器将隐式添加一个。
因此,如果两者都被允许,您最终可能会调用super
构造函数两次。
示例(不要在参数中寻找意义):
class A {
public A() {
this( false );
}
public A(boolean someFlag) {
}
}
class B extends A {
public B() {
super();
}
public B( boolean someFlag ) {
super( someFlag );
}
public B ( int someNumber ) {
this(); //
}
}
现在,如果您调用new B(5)
以下构造函数,则会调用:
this( false);
A() ---------------> A(false)
^
|
| super();
|
| this();
B() <--------------- B(5) <--- you start here
更新:
如果你能够使用this()
并且super()
你最终可能会得到这样的结果:
(注意:这是为了表明如果您被允许这样做,可能会出现什么问题- 幸运的是,您没有这样做)
this( false);
A() ---------------> A(false)
^ ^
| |
| super(); | super( true ); <--- Problem: should the parameter be true or false?
| |
| this(); |
B() <--------------- B(5) <--- you start here
如您所见,您会遇到一个问题,即A(boolean)
可以使用不同的参数调用构造函数,您现在必须以某种方式决定应该使用哪个。此外,其他构造函数 ( A()
and B()
) 可能包含现在可能无法正确调用的代码(即乱序等),因为调用 tosuper( true )
会绕过它们而this()
不会。
super()
和之间有区别this()
。
super()
- 调用基类构造函数,而
this()
- 调用当前类构造函数。
this()
和都是super()
构造函数调用。
构造函数调用必须始终是第一条语句。所以你要么有super()
要么this()
作为第一个陈述。
this()
和都是super()
构造函数调用,构造函数调用必须是构造函数中的第一个(也是唯一一个)调用。否则,Object
在实例化单个对象时将多次调用构造函数。
两者都有一个条件,它们必须在您使用的构造函数的第一行中声明。这就是为什么我们不能在单个构造函数中同时使用两者的原因,因为您只能在第一行中编写一个东西。
因为没有意义。构造函数必须调用this()
或super()
(隐式或显式)。this()
调用另一个构造函数,该构造函数必须像以前一样调用this()
orsuper()
等。一个调用两者的构造函数,this()
因此super()
最终会调用super()
两次。
因为如果在构造函数中同时使用this()
andsuper()
会产生编译时错误。因为this()
andsuper()
必须是第一个可执行语句。如果你this()
先写比super()
将成为第二个语句,反之亦然。这就是为什么我们不能一起使用this()
和super()
。
this() 和 super() 不能在构造函数中一起使用。
this() 用于调用同一个类的默认构造函数。它应该是构造函数中的第一个语句。
super() 用于调用基类的默认构造函数。它应该是构造函数中的第一个语句。
所以 this() 和 super() 都用于构造函数调用,但都想首先执行。这就是为什么它会显示编译器错误,例如:
错误:调用 this 必须是构造函数 this() 中的第一条语句;或者
错误:调用 this 必须是构造函数 super() 中的第一条语句;
比较下面的例子。FirstChild 类在 2 个构造函数中设置实例变量名称,因为从第一个构造函数调用第二个构造函数被排除在调用 super() 之外。
在 SecondChild 类中引入了第三个私有构造函数,它接受 2 个参数——第一个传递给 supper(),第二个用于设置名称。前 2 个构造函数正在调用第三个。Super() 只被调用一次,实例变量也只在一个构造函数中设置。代码产生相同的结果,无需在同一个构造函数中调用 super() 和 this()。
class FirstChild extends ConstructorTest{
private String name = null;
public FirstChild(){
super("super text 1");
//this("Unknown"); //UNCOMMENTED DOES NOT COMPILE
name = "Unknown";
}
public FirstChild(String name){
super("super text 2");
this.name = name;
}
public String getName(){
return name;
}
}
class SecondChild extends ConstructorTest{
private String name = null;
public SecondChild(){
this("super text 1", "Unknown");
}
public SecondChild(String name){
this("super text 2", name);
}
private SecondChild(String superStr, String name)
{
super(superStr);
this.name = name;
}
public String getName(){
return name;
}
}
public class ConstructorTest{
public ConstructorTest(String str){
System.out.println("ConstructorTest constructor called with parameter \"" + str + "\"");
}
public static void main(String... args)
{
System.out.println("Hello from main, FirstChild results:");
FirstChild fc1 = new FirstChild();
FirstChild fc2 = new FirstChild("John");
System.out.println(" child fc1 name: " + fc1.getName());
System.out.println(" child fc2 name: " + fc2.getName());
System.out.println("Hello from main, SecondChild results:");
SecondChild sc1 = new SecondChild();
SecondChild sc2 = new SecondChild("John");
System.out.println(" child sc1 name: " + sc1.getName());
System.out.println(" child sc2 name: " + sc2.getName());
}
}
this() 和 super() 都是构造函数,所以必须是第一个语句。但是我们可以在一个程序中同时使用它们。
this():用于调用同类默认或参数化构造函数。
super():用于调用直接超/父类默认或参数化构造函数。
//Super Class
public class SuperConstructor {
SuperConstructor(){
this(10);
System.out.println("Super DC");
}
SuperConstructor(int a){
this(10,20);
System.out.println("Suer SPC with Iteger");
}
SuperConstructor(int i,int j){
System.out.println("Super with DPC with Iteger and Integer");
}
}
//subclass
public class ThisConstructor extends SuperConstructor{
ThisConstructor(){
this(10,20);
System.out.println("Subcalss DC ");//DC Default Constructor
}
ThisConstructor(int i){
super(i);
System.out.println("Subcalss SPC with Iteger");//SPC Single Parameterized Constructor
}
ThisConstructor(int i, String s){
this();
System.out.println("Subcalss DPC with Iteger and String");//DPC double Parameterized Constructor
}
ThisConstructor(int i,int age){
super(i,age);
System.out.println("Subcalss DPC with Iteger and Integer");
}
public static void main(String []k){
System.out.println("=================Frist time Calling ==========================\n");
ThisConstructor t = new ThisConstructor(1);
System.out.println("=================Second time Calling ==========================\n");
ThisConstructor t1 = new ThisConstructor(1,2);
}
}
super() - 引用直接父类实例。可用于调用直接父类方法。this() - 引用当前类实例。可用于调用当前类方法。
由于构造函数调用必须是方法中的第一条语句,所以如果我们在一个方法中同时定义 this 和 super 构造函数,就会产生如下冲突。假设首先调用此构造函数,那么它将检查当前类构造函数,如果在当前类构造函数中我们有另一个方法调用或语句。所以在这个调用中,当前类构造函数中的所有方法和语句都会在调用超类构造函数之前被调用,然后它会拒绝语句“构造函数调用必须是方法中的第一个语句”