Java中super()和this()的区别
Super和这个关键字Super()以及this()关键字都用于调用构造函数。super()用于调用基类的构造函数(i.e, Parent的类),而this()用于调用当前类的构造函数。让我们来详细地看看它们:
super()
super()用于调用基类(父类)的构造函数。
// Java code to illustrate usage of super()
class Parent {
Parent()
{
System.out.println("Parent class's No " +
" arg constructor");
}
}
class Child extends Parent {
Child()
{
super();
System.out.println("Flow comes back from " +
"Parent class no arg const");
}
public static void main(String[] args)
{
new Child();
System.out.println("Inside Main");
}
}
输出:
Parent class's No arg constructor
Flow comes back from Parent class no arg const
Inside Main
程序流程:
- 在main中,我们创建了new Child()语句,因此它调用Child类的无参数构造函数。
- 在里面我们有super(),它调用Parent类的无参数,因为我们写了super(),而且没有参数,这就是为什么它不调用Parent类的参数构造函数,因为我们有一个SOP语句,因此它打印 父类的无参数构造函数 .
- 现在,由于父类的无参数常量完成了,所以流回到了子类的无参数常量,在此我们有一个SOP语句,因此它打印出流从父类的无参数常量回来。
- 在完成子类flow的无参数构造函数之后,现在再次返回到main并执行剩下的语句和打印 在主要 .
我们只能在构造函数内部使用super(),而不能在其他地方使用,即使在静态上下文中也不能,即使在方法内部,super()也不能作为构造函数内部的第一条语句。
// Java program to illustrate usage of
// super() as first statement
class Parent {
Parent()
{
System.out.println("Parent class's No " +
"arg constructor");
}
}
class Child extends Parent {
Child()
{
// Uncommenting below line causes compilation
// error because super() should be first statement
// System.out.println("Compile Time Error");
super();
System.out.println("Flow comes back from " +
"Parent class no arg const");
}
public static void main(String[] args)
{
new Child();
System.out.println("Inside main");
}
}
输出:
Parent class's No arg constructor
Flow comes back from Parent class no arg const
Inside main
注意:super()应该是任何构造函数中的第一条语句。它只能在构造函数内部使用,不能在其他地方使用。Super()只用于引用父类(超类)的构造函数。
this()
This()用于调用当前类的构造函数。
// Java code to illustrate usage of this()
class RR {
RR()
{
this(10);
System.out.println("Flow comes back from " +
"RR class's 1 arg const");
}
RR(int a)
{
System.out.println("RR class's 1 arg const");
}
public static void main(String[] args)
{
new RR();
System.out.println(" Inside Main & quot;);
}
}
输出:
RR class's 1 arg const
Flow comes back from RR class's 1 arg const
Inside Main
程序流程:
- 首先,从main开始,然后我们创建了一个语句new Child()因此调用Child类的无参数构造函数,在这个语句中我们有this(10)调用当前类的1参数(i.e, RR类)
- 因为我们已经写了这个(10)和一个参数,这就是为什么它调用RR类的一个参数构造函数。其中,我们有一条SOP语句,因此它会打印 RR类的1个参数为常量 .
- 现在,当RR类的1参数const完成时,流返回到RR类的无参数,在那里我们有一个SOP语句,因此它打印 流从RR类的1参数const返回 .
- 在完成RR类流的无参数构造函数之后,现在再次返回到main并执行剩下的语句和打印 在主要 .
我们只能在构造函数中使用this()而不能在其他地方使用,即使在静态环境中也不能,即使在方法中也不能,而this()应该是构造函数中的第一条语句。
// Java program to illustrate usage of
// this() as first statement
class RR {
RR()
{
// Uncommenting below line causes compilation
// error because this() should be first statement
// System.out.println("Compile Time
// Error");
this(51);
System.out.println(
" Flow comes back from RR & quot; + "
class 1 arg const& quot;);
}
RR(int k)
{
System.out.println("RR class's 1 arg const");
}
public static void main(String[] args)
{
new RR();
System.out.println(" Inside main & quot;);
}
}
输出:
RR class's 1 arg constructor
Flow comes back from RR class 1 arg const
Inside main
注意:this()应该是任何构造函数中的第一个语句。它只能在构造函数内部使用,不能在其他地方使用。This()只用于引用当前类的构造函数。
this()和super()的要点
- 我们也可以在构造函数中使用super() this(),但只能使用一次。如果我们两次使用super()或this()或super()后接this()或this()后接super(),那么立即会得到编译时错误i.e,我们可以在构造函数中使用super()或this()作为第一条语句,而不是两者都使用。
- 是否使用super()或this()由你决定,因为如果我们不使用this()或super(),那么默认情况下编译器将把super()作为构造函数中的第一个语句。
示例:
// Java program to illustrate super() by default
// executed by compiler if not provided explicitly
class Parent {
Parent()
{
System.out.println("Parent class's No " +
"argument constructor");
}
Parent(int a)
{
System.out.println("Parent class's 1 argument" +
" constructor");
}
}
class Base extends Parent {
Base()
{
// By default compiler put super()
// here and not super(int)
System.out.println("Base class's No " +
"argument constructor");
}
public static void main(String[] args)
{
new Base();
System.out.println("Inside Main");
}
}
Output:
Parent class's No argument constructor
Base class's No argument constructor
Inside Main
程序流程:
- 在main中,我们有新的Base(),然后流进入Base类的No参数构造函数。
- 在此之后,如果我们不放入super()或this(),则默认编译器会放入super()。
- 所以流进入父类的No参数构造函数,而不是1参数构造函数。
- 之后,它打印 父类的无参数构造函数 .
- 之后,当Parent()构造函数完成时,流再次返回到Base类的No参数构造函数,并执行下一个SOP语句i.e, 基类的无参数构造函数 .
- 在完成了RR类的无参数构造函数后,现在又回到了main,执行剩余的语句并打印出Main内部。
我们只能在构造函数中使用this(),而不能在其他地方使用,甚至在静态上下文中也不能在方法中使用,而且this()应该是构造函数中的第一个语句。
// Java program to illustrate recursive
// constructor call not allowed
class RR {
RR() { this(30); }
RR(int a) { this(); }
public static void main(String[] args) { new RR(); }
}
输出:
Compile time error saying recursive constructor invocation
程序流程:在这里,上面从main()开始,然后流程转到RR类的No参数构造函数。在那之后,我们有this(30)和flow进入RR的一个参数构造函数,在那里我们有this(),所以flow再次进入基类的No参数构造函数,在那里我们再次有this(30)和flow再次进入基类的一个参数构造函数,它像递归一样进入……。所以它是无效的这就是为什么我们会得到一个编译时错误说 递归构造函数调用 . 所以java中不允许递归构造函数调用。
让我们用如下表格的形式来看看它们的区别:
super() | this() |
---|---|
Super()调用父构造函数 | 可以使用This()调用当前的类构造函数 |
它可以用来调用来自父类的方法。 | 它可以作为方法调用中的参数传递。 |
它不带参数返回。 | 它可以作为构造函数调用中的参数传递。 |
它可以与实例成员一起使用。 | 它用于从方法返回当前类实例。 |