📜  Java中的super和this关键字

📅  最后修改于: 2022-05-13 01:54:59.400000             🧑  作者: Mango

Java中的super和this关键字

super 关键字用于访问父类的方法, this 用于访问当前类的方法。

这个关键字

  1. 是Java中的保留关键字,即我们不能将其用作标识符。
  2. this用于引用当前类的实例以及静态成员。

可以在各种情况下使用,如下所示:

  • 引用当前类的实例变量
  • 调用或启动当前类构造函数
  • 可以在方法调用中作为参数传递
  • 可以在构造函数调用中作为参数传递
  • 可用于返回当前类实例
Java
// Program to illustrate this keyword
// is used to refer current class
class RR {
    // instance variable
    int a = 10;
 
    // static variable
    static int b = 20;
 
    void GFG()
    {
        // referring current class(i.e, class RR)
        // instance variable(i.e, a)
        this.a = 100;
 
        System.out.println(a);
 
        // referring current class(i.e, class RR)
        // static variable(i.e, b)
        this.b = 600;
 
        System.out.println(b);
    }
 
    public static void main(String[] args)
    {
        // Uncomment this and see here you get
        // Compile Time Error since cannot use
        // 'this' in static context.
        // this.a = 700;
        new RR().GFG();
    }
}


Java
// Program to illustrate super keyword
// refers super-class instance
 
class Parent {
    // instance variable
    int a = 10;
 
    // static variable
    static int b = 20;
}
 
class Base extends Parent {
    void rr()
    {
        // referring parent class(i.e, class Parent)
        // instance variable(i.e, a)
        System.out.println(super.a);
 
        // referring parent class(i.e, class Parent)
        // static variable(i.e, b)
        System.out.println(super.b);
    }
 
    public static void main(String[] args)
    {
        // Uncomment this and see here you get
        // Compile Time Error since cannot use 'super'
        // in static context.
        // super.a = 700;
        new Base().rr();
    }
}


Java
// Java Program to illustrate using this
// many number of times
 
class RRR {
    // instance variable
    int a = 10;
 
    // static variable
    static int b = 20;
 
    void GFG()
    {
        // referring current class(i.e, class RR)
        // instance variable(i.e, a)
        this.a = 100;
 
        System.out.println(a);
 
        // referring current class(i.e, class RR)
        // static variable(i.e, b)
        this.b = 600;
 
        System.out.println(b);
 
        // referring current class(i.e, class RR)
        // instance variable(i.e, a) again
        this.a = 9000;
 
        System.out.println(a);
    }
 
    public static void main(String[] args)
    {
        new RRR().GFG();
    }
}


Java
// Java Program to illustrate using super
// many number of times
 
class Parent {
    // instance variable
    int a = 36;
 
    // static variable
    static float x = 12.2f;
}
 
class Base extends Parent {
    void GFG()
    {
        // referring super class(i.e, class Parent)
        // instance variable(i.e, a)
        super.a = 1;
        System.out.println(a);
 
        // referring super class(i.e, class Parent)
        // static variable(i.e, x)
        super.x = 60.3f;
 
        System.out.println(x);
    }
    public static void main(String[] args)
    {
        new Base().GFG();
    }
}


Java
// Java program to illustrate
// the usage of this keyword
 
class RR {
    int first = 22;
    int second = 33;
 
    void garcia(int a, int b)
    {
        a = this.first;
        b = this.second;
        System.out.println(first);
        System.out.println(second);
        System.out.println(a);
        System.out.println(b);
    }
 
    void louis(int m, int n)
    {
        this.first = m;
        this.second = n;
        System.out.println(first);
        System.out.println(second);
        System.out.println(m);
        System.out.println(n);
    }
 
    public static void main(String[] args)
    {
        new RR().garcia(100, 200);
        new RR().louis(1, 2);
    }
}


Java
class Vehicle {
    Vehicle() { System.out.println("Vehicle is created."); }
}
 
class Bike extends Vehicle {
    Bike() { System.out.println("Bike is created."); }
 
    Bike(String brand)
    {
        super(); // it calls Vehicle(), the parent class
                 // constructor of class Bike
        this();
        System.out.println("Bike brand is " + brand);
    }
}
 
public class GFG {
    public static void main(String args[])
    {
        Bike bike = new Bike("Honda");
    }
}


100
600


超级关键字

  1. super是Java中的保留关键字,即我们不能将其用作标识符。
  2. super用于引用超类的实例以及静态成员
  3. super也用于调用超类的方法或构造函数

Java

// Program to illustrate super keyword
// refers super-class instance
 
class Parent {
    // instance variable
    int a = 10;
 
    // static variable
    static int b = 20;
}
 
class Base extends Parent {
    void rr()
    {
        // referring parent class(i.e, class Parent)
        // instance variable(i.e, a)
        System.out.println(super.a);
 
        // referring parent class(i.e, class Parent)
        // static variable(i.e, b)
        System.out.println(super.b);
    }
 
    public static void main(String[] args)
    {
        // Uncomment this and see here you get
        // Compile Time Error since cannot use 'super'
        // in static context.
        // super.a = 700;
        new Base().rr();
    }
}
10
20


this 和 super 的相似之处

1)我们可以在除静态区域之外的任何地方使用this以及super 。上面已经显示了这个例子,我们在 public static void main(String[]args) 中使用 this 以及 super ,因此我们得到编译时错误,因为不能在静态区域内使用它们。
2)我们可以在程序中多次使用this以及super

Java

// Java Program to illustrate using this
// many number of times
 
class RRR {
    // instance variable
    int a = 10;
 
    // static variable
    static int b = 20;
 
    void GFG()
    {
        // referring current class(i.e, class RR)
        // instance variable(i.e, a)
        this.a = 100;
 
        System.out.println(a);
 
        // referring current class(i.e, class RR)
        // static variable(i.e, b)
        this.b = 600;
 
        System.out.println(b);
 
        // referring current class(i.e, class RR)
        // instance variable(i.e, a) again
        this.a = 9000;
 
        System.out.println(a);
    }
 
    public static void main(String[] args)
    {
        new RRR().GFG();
    }
}
100
600
9000


见上文,我们已经使用3 次。所以可以使用任意次数。

Java

// Java Program to illustrate using super
// many number of times
 
class Parent {
    // instance variable
    int a = 36;
 
    // static variable
    static float x = 12.2f;
}
 
class Base extends Parent {
    void GFG()
    {
        // referring super class(i.e, class Parent)
        // instance variable(i.e, a)
        super.a = 1;
        System.out.println(a);
 
        // referring super class(i.e, class Parent)
        // static variable(i.e, x)
        super.x = 60.3f;
 
        System.out.println(x);
    }
    public static void main(String[] args)
    {
        new Base().GFG();
    }
}
1
60.3


见上文,我们已经使用了super 2 次。所以super可以使用任意次数。
注意:我们可以多次使用“this”和“super”,但主要是我们不能在静态上下文中使用它们。
让我们考虑这个关键字的一个棘手的例子:

Java

// Java program to illustrate
// the usage of this keyword
 
class RR {
    int first = 22;
    int second = 33;
 
    void garcia(int a, int b)
    {
        a = this.first;
        b = this.second;
        System.out.println(first);
        System.out.println(second);
        System.out.println(a);
        System.out.println(b);
    }
 
    void louis(int m, int n)
    {
        this.first = m;
        this.second = n;
        System.out.println(first);
        System.out.println(second);
        System.out.println(m);
        System.out.println(n);
    }
 
    public static void main(String[] args)
    {
        new RR().garcia(100, 200);
        new RR().louis(1, 2);
    }
}
//it is of S.O.P(first) of garcia method
22
//it is of S.O.P(second) of garcia method
33
//it is of S.O.P(a) of garcia method
22
//it is of S.O.P(b) of garcia method
33
//it is of S.O.P(first) of louis method
1
//it is of S.O.P(second) of louis method
2
//it is of S.O.P(m) of louis method
1
//it is of S.O.P(n) of louis method
2


程序流程:首先,它从 main 开始,然后我们有new RR().garcia(100, 200)然后流程转到 RR 类的 garcia 方法,然后我们有

a = this.first
b = this.second 

在这里,发生的事情是实例变量的值(即第一个)和静态变量的值(即第二个)分别分配给 garcia 方法的局部变量 a 和 b。因此 a 和 b 的值分别为 22 和 33。接下来我们有new RR().louis(1, 2)因此这里的流程转到 RR 类的 louis 方法,我们有

this.first = m
this.second = n

在这里,上面发生的情况是 louis 方法的局部变量(即 m 和 n)的值以及静态变量(即分别为 first 和 second)分配给实例。
因此,第一个和第二个变量的值与我们传递给 louis 方法的值相同,即分别为 1 和 2。

我们可以在同一个构造函数中同时使用 this() 和 super() 吗?

这里要注意的一件有趣的事情是,根据Java指南,this() 或 super() 必须是构造函数块中的第一条语句才能执行。所以我们不能将它们放在同一个构造函数中,因为它们都需要成为块中的第一条语句才能正确执行,这是不可能的。尝试这样做会引发编译器错误。

Java

class Vehicle {
    Vehicle() { System.out.println("Vehicle is created."); }
}
 
class Bike extends Vehicle {
    Bike() { System.out.println("Bike is created."); }
 
    Bike(String brand)
    {
        super(); // it calls Vehicle(), the parent class
                 // constructor of class Bike
        this();
        System.out.println("Bike brand is " + brand);
    }
}
 
public class GFG {
    public static void main(String args[])
    {
        Bike bike = new Bike("Honda");
    }
}

在运行上面的程序时,我们在第 12 行得到一个错误,说“对 this 的调用必须是构造函数中的第一个语句”。这是因为我们尝试同时使用 super() 和 this()。虽然 super() 是构造函数的第一行,但 this() 语句违反了它应该是第一行的条件,因此引发了错误。

编译错误:

prog.java:12: error: call to this must be first statement in constructor
        this();
            ^
1 error