Java中super()和this()的区别

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()的要点

  1. 我们也可以在构造函数中使用super() this(),但只能使用一次。如果我们两次使用super()或this()或super()后接this()或this()后接super(),那么立即会得到编译时错误i.e,我们可以在构造函数中使用super()或this()作为第一条语句,而不是两者都使用。
  2. 是否使用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()调用当前的类构造函数
它可以用来调用来自父类的方法。 它可以作为方法调用中的参数传递。
它不带参数返回。 它可以作为构造函数调用中的参数传递。
它可以与实例成员一起使用。 它用于从方法返回当前类实例。

Python教程

Java教程

Web教程

数据库教程

图形图像教程

大数据教程

开发工具教程

计算机教程