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()你的榜样。
请原谅我的问题,因为我试图搜索使用 super 关键字与 class 名称从 super class 调用方法之间的区别,但找不到答案。 我的问题是我正在尝试将 Java 作为学习课程学习,并且正在使用 link 中的示例:http://www.javatpoint.com/super-keyword 使用示例 # 3,这是我编写的代码:
我创建了一个名为 Vehicle
的超级 classpublic 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()你的榜样。