📜  Javasuper()和this()的区别

📅  最后修改于: 2021-09-11 06:23:22             🧑  作者: Mango

类似文章:super 和 this 关键字
super() 和 this() 都用于进行构造函数调用。 super() 用于调用Base类的构造函数(即Parent 的类),而this() 用于调用当前类的构造函数。

让我们详细看看它们:

极好的()

  1. 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()调用父类的无参数,因为我们已经编写了 super() 并且没有参数这就是为什么它调用父类的无参数构造函数,因为我们有一个 SOP 语句,因此它打印父类的 No arg 构造函数
    • 现在,随着父类的无参数 const 完成,流返回到子类的无参数,因为我们有一个 SOP 语句,因此它打印流从父类返回无参数常量
    • 此外,在完成子类流的无参数构造函数之后,现在又回到 main 并执行剩余的语句并打印Inside Main
  2. 我们只能在构造函数中使用 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() 仅用于引用父类(超类)的构造函数

这()

  1. 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");
        }
    }
    

    输出:

    RR class's 1 arg const
    Flow comes back from RR class's 1 arg const
    Inside Main
    

    程序流程

    • 首先从 main 开始,然后我们做了一个声明new Child()因此它调用了 Child 类的无参数构造函数,在里面我们有this(10)它调用当前类(即 RR 类)的 1 个参数
    • 由于我们已经编写了 this(10) 和 1 个参数,这就是它调用 RR 类的 1 个参数构造函数的原因。因为我们有一个 SOP 语句,因此它打印了RR 类的 1 arg const
    • 现在,当 RR 类的 1 个参数 const 完成时,流返回到 RR 类的无参数,因为我们有一个 SOP 语句,因此它打印Flow 来自 RR 类的 1 arg const
    • 此外,在完成 RR 类流的无参数构造函数之后,现在又回到 main 并执行剩余的语句并打印Inside Main
  2. 我们只能在构造函数中使用 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 " + 
                                     "class 1 arg const");
        }
        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");
        }
    }
    

    输出:

    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(),那么我们立即得到编译时错误,即,我们可以使用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 内部,我们有new Base()然后流程转到 Base 类的无参数构造函数
    • 之后,如果我们不放置 super() 或 this() ,那么默认情况下编译器放置 super()
    • 所以流程转到Parent 类的 No arg constructor而不是 1 argument constructor
    • 之后,它打印Parent 类的 No argument constructor
    • 之后,当家长()构造完成,然后再流回来没有基类,并执行下一个SOP声明即,基类的无参数的构造函数的参数的构造函数
    • 完成后,无参数构造函数流再次返回到 main()并打印main() 中的剩余语句,即Inside main

    但是,如果明确指定,您可以在 super 之前使用 this()。

    // Java program to illustrate super() put by 
    // compiler always 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 one " + 
                               " argument constructor");
        }
    }
      
    class Base extends Parent {
        Base()
        {
            this(10);
            System.out.println("No arg const");
        }
        Base(int a)
        {
            this(10, 20);
            System.out.println("1 arg const");
        }
        Base(int k, int m)
        {
            // See here by default compiler put super();
            System.out.println("2 arg const");
        }
        public static void main(String[] args)
        {
            new Base();
            System.out.println("Inside Main");
        }
    }
    

    输出:

    Parent class's No argument constructor
    2 arg const
    1 arg const
    No arg const
    Inside Main
    
  3. 不允许递归构造函数调用
    // 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 arg 构造函数。之后,我们有了this(30)并且流程转到RR 的 1 个 arg 构造函数,因为我们有了this(),所以流程再次转到了基类的 No arg 构造函数,然后我们又有了 this(30) 并且流程再次转到了到 Base 类的 1 个 arg 构造函数,它继续……就像递归一样。所以它是无效的,这就是为什么我们会得到编译时错误,recursive constructor invocation 。因此在Java不允许递归构造函数调用。