super 关键字与 class 从 super class 调用方法的名称之间的区别

Difference between super keyword vs class name to call method from super class

请原谅我的问题,因为我试图搜索使用 super 关键字与 class 名称从 super class 调用方法之间的区别,但找不到答案。 我的问题是我正在尝试将 Java 作为学习课程学习,并且正在使用 link 中的示例:http://www.javatpoint.com/super-keyword 使用示例 # 3,这是我编写的代码:

我创建了一个名为 Vehicle

的超级 class
public class Vehicle {
    Vehicle() {
        System.out.println("Vehicle constructor created");
    }

    public void speed() {
        int a = 20;
        System.out.println(a);
    }

}

然后使用以下代码创建了一个名为 Bike 的子 class:

public class Bike extends Vehicle {
    int speed;

    Bike(int speed1) {
        this.speed = speed1;
        System.out.println(speed1);
        super.speed();

    }

    public static void main(String args[]) {
        Bike b = new Bike(10);

    }

}

在 Bike 构造函数下的子 class 中,我使用 super.speed() 从 super (Vehicle) class 调用速度方法。现在,如果我将此行更改为 Vehicle.speed(),我会收到一条错误消息,指出我需要将我的速度方法设为静态。

我不想让我的方法成为静态的,想知道它们之间的区别。

干杯,

非静态方法只能在对象的特定实例上调用。这就是为什么调用 Vehicle.speed() 只有在 speed 方法是静态的情况下才有效。你可以调用 super.speed() 的原因是因为在构造函数中,你已经构造了车辆对象,并且基本上是在你正在构造的对象上调用方法。

对于上面的例子,我认为调用 super.speed() 是最好的方法。

此外,由于您没有覆盖 speed 方法的超级实现,您可以轻松地调用 this.speed()speed()。这种方法意味着如果您决定 Bike 需要 speed 方法中的不同功能,您的特定实现将被调用而不是默认实现。

这两个构造不等价。

当调用 Vehicle.speed() 时,编译器会在名为 Vehicle 的 class 中查找名为 speed()static 方法。静态方法不属于 class 的任何实例。您不能在静态方法中使用任何实例变量。您还没有在 Vehicle class 中定义名为 speed() 的静态方法,因此没有 Vehicle.speed() 这样的东西。因此,你会得到一个编译错误。

当调用 super.speed() 时,您不会像前面的情况那样寻找 static 方法:使用super 语法是在当前对象的 superclass 中定义的 instance 方法(在您的例子中名为 speed() )。即super.speed()是当前对象的superclass中定义的实例方法(不像this.speed()是实际[=38中定义的名为speed()的实例方法=] 当前对象)。换句话说,它将调用 class Vehicle 中定义的方法 speed(),但 this 参数将成为 [=25= 引用的方法] ], 当前对象。

如果你想直接使用带有 class 名称的方法,那么你必须将方法指定为静态

public static void speed() {
    int a = 20;
    System.out.println(a);
}

你可以像这样class在你的subsclass中创建一个class车辆和访问速度方法的对象

Bike(int speed1) {
    this.speed = speed1;
    System.out.println(speed1);
    Vehicle vehicle = new Vehicle();
    vehicle.speed();
}

调用直接使用class名称的方法意味着你要调用一个静态方法,它与class的任何object无关,但class 它自己。 这就是为什么编译器告诉你该方法必须是静态的。

至于你的问题,当你创建一个 child class 的 object(本例中的自行车 class)时,它的 object parent 总是被创建,在此基础上创建特定的 child object。

这就像,每当您创建 Bike 时,总是会创建支持 Vehicle,并基于此创建 Bike。否则 Bike 就不会是 Vehicle.

所以通过 super 调用一个方法意味着,你告诉编译器在 class 上调用这个方法,它被用作基础(parent)来制作这个 Bike class,我从中调用此方法。

当您通过 class 名称调用方法时,您是在告诉编译器调用 Vehicle class 的此方法,它与任何 [=11] 无关=] object/instance(显然与任何 child 无关(例如 Bike object 或实例)

hi super 是一个关键字,用于访问 sub class 中的 super class 方法。 这个super关键字主要用在重写方法的时候。

例子

class A    
{       
    method m()        
}

class B extends A     
{       
   method m()        

   method m1()   
   {        
       super.m()          
   }        
}

class C
{
   public static void main(String args[])   
   {   
        B b = new B(); 

        b.m()  // calls method m() in class B
        b.m1()  // calls method m() in class A because method m is pointing to  super class method 
     }   
}

您需要实例来调用实例(non-static) 方法。

super 是 parent class 的实例。简单地说 class name 不是实例(它是整个 class 的静态上下文)。

[super是parentclass的实例?]

Jon skeet said 没有 "parent instance" 这样的东西,但我怀疑实例这个词。

super的变量先初始化,然后轮流child决定是否共享相同的variable/method(即这种方法中的return this.i;会returnsuper.i,而不是 this.i,当被 child 调用时)或覆盖它。

import java.util.Random;
class Love {

    int i = 1;
    int hole() {
        return this.i;
    }
}

class Main extends Love {

    void wrapper() {
        System.out.println(super.i); //1
        System.out.println(this.i); //2
        super.i = new Random().nextInt(50) + 2; //to avoid compiler pre-optimizing hard coded return value in hole(), so we set again.
        System.out.println(super.i); //23
        i = 3; //2nd attempt override
        this.i = 3; //3rd attempt override
        System.out.println(hole()); //23, super "instance" keep its own version of this.i
    }

    int i = 2; //1st attempt oveeride
    public static void main(String[] args) {
        new Main().wrapper();
    }

}

所以当 child 覆盖时很明显,super 仍然保留它自己的版本,所以恕我直言,super 可以粗略地当作一个 parent 实例,与普通实例的不同之处在于它是一些关键字使用限制(例如 super.super.i 是不允许的,直接打印 super 是不允许的)。另一个区别是变量值将在每个实例中同步,因为 child 可能会如上所述共享它。

你可以尝试在静态方法中打印super.variable_name,它会输出super is a non-static variable:

$ javac Bike.java 
Bike.java:132: error: non-static variable super cannot be referenced from a static context
        System.out.println(super.dummy); 
                           ^
Bike.java:132: error: cannot find symbol
        System.out.println(super.dummy); 
                                ^
  symbol: variable dummy
2 errors
$ 

所以超级有意义,因为 non-static 变量可以访问 non-static 方法 speed()你的榜样。