Java继承:为什么引用超类变量
我有一个超级班“Sam”和一个子班“SubSam” 输出为:Java继承:为什么引用超类变量,java,Java,我有一个超级班“Sam”和一个子班“SubSam” 输出为: A B 为什么“toString()”引用的是“Sam”的实例字段而不是“SubSam”。输出应该是:A C 我已经考虑了很长一段时间了,但是没有得到什么?,因为Java中的实例变量并没有被覆盖,非常简单。一个子类可以定义一个与它的一个超类中定义的变量同名的变量,但在所有意图和目的中,它都算作一个单独的变量 例如,考虑下面的代码: public class A { public String var; } public
A B
为什么“toString()”引用的是“Sam”的实例字段而不是“SubSam”。输出应该是:A C
我已经考虑了很长一段时间了,但是没有得到什么?,因为Java中的实例变量并没有被覆盖,非常简单。一个子类可以定义一个与它的一个超类中定义的变量同名的变量,但在所有意图和目的中,它都算作一个单独的变量
例如,考虑下面的代码:
public class A {
public String var;
}
public class B extends A {
public int var;
}
根据这些定义,B
的实例将有两个变量,一个是String
类型,另一个是int
类型,但两者都将命名为var
。它们仍然是独立的变量,可以独立分配和读取,java不认为有任何错误。
如果您想按照自己的意愿覆盖行为,则需要改用方法。例如,您可以这样做:
public class A {
public String msg;
private String msg1;
public A(String mm, String mm1) {
this.msg = mm;
this.msg1 = mm1;
}
public String msg1() {
return(this.msg1);
}
@Override
public String toString() {
return(this.msg + " " + msg1());
}
}
public class B extends A {
public B() {
super("A", "B");
}
@Override
public String msg1() {
return("C");
}
}
现在,如果调用
System.out.println(new B())代码>,它将打印C
,因为Java中的实例变量并没有被覆盖,非常简单。一个子类可以定义一个与它的一个超类中定义的变量同名的变量,但在所有意图和目的中,它都算作一个单独的变量
例如,考虑下面的代码:
public class A {
public String var;
}
public class B extends A {
public int var;
}
根据这些定义,B
的实例将有两个变量,一个是String
类型,另一个是int
类型,但两者都将命名为var
。它们仍然是独立的变量,可以独立分配和读取,java不认为有任何错误。
如果您想按照自己的意愿覆盖行为,则需要改用方法。例如,您可以这样做:
public class A {
public String msg;
private String msg1;
public A(String mm, String mm1) {
this.msg = mm;
this.msg1 = mm1;
}
public String msg1() {
return(this.msg1);
}
@Override
public String toString() {
return(this.msg + " " + msg1());
}
}
public class B extends A {
public B() {
super("A", "B");
}
@Override
public String msg1() {
return("C");
}
}
现在,如果调用
System.out.println(new B())
,它将打印一个C您没有覆盖toString,因此调用超类的toString方法。它为超类而不是子类打印msg和msg1。您没有重写toString,因此调用了超类的toString方法。它为超类而不是子类打印msg和msg1。您正在子类中设置msg1
,但在它的构造函数中您正在传递
super("A","B");
此时,在
super
中初始化的变量,即主类的构造函数是使用toString
方法中的this
关键字使用的主类变量。您在子类中设置msg1
,但在它的构造函数中传递
super("A","B");
此时,在
super
中初始化的变量,即主类的构造函数是使用toString
方法中的this
关键字使用的主类变量。您遇到的问题称为“阴影”-看看这个@Luiggi Mendoza:当我调试时,“this.msg1”显示为“C”,但在打印时它显示为“B”。为什么?您遇到的问题被称为“阴影”-看看这个@Luiggi Mendoza:当我调试时,“this.msg1”显示“C”,但在打印时它打印“B”。为什么?当我调试时,“this.msg1”显示为“C”,但在打印时显示为“B”。为什么?因为您的SubSam
实例实际上不是一个而是两个名为msg1
的变量,一个由Sam
类定义,另一个由SubSam
类定义。Sam
类中定义的代码是指Sam
类中定义的变量,该变量被赋值为“B”
,而SubSam
类中定义的代码是指SubSam
类中定义的变量,该变量被赋值为“C”
。您的调试器可能只显示其中一个,因为使用相同的名称定义变量是不寻常的做法。但我正在打印“SubSam”类的对象,因此在“toString()”中,“this”应该指“SubSam instance”?否,因为toString
方法是在Sam
类中定义的,因此,它引用了其中定义的变量这个
确实引用了一个SubSam
实例,但是toString
代码引用了Sam
类定义的msg1
变量,因为编译toString
方法时该名称就是这样解析的。当我调试时,“this.msg1”显示“C”,但在打印时,它正在打印“B”。为什么?因为您的SubSam
实例实际上不是一个而是两个名为msg1
的变量,一个由Sam
类定义,另一个由SubSam
类定义。Sam
类中定义的代码是指Sam
类中定义的变量,该变量被赋值为“B”
,而SubSam
类中定义的代码是指SubSam
类中定义的变量,该变量被赋值为“C”
。您的调试器可能只显示其中一个,因为使用相同的名称定义变量是不寻常的做法。但我正在打印“SubSam”类的对象,因此在“toString()”中,“this”应该指“SubSam instance”?否,因为toString
方法是在Sam
类中定义的,因此,它引用了其中定义的变量这个
确实引用了一个SubSam
实例,但是toString
代码引用了Sam
类定义的msg1
变量,因为编译toString
方法时该名称就是这样解析的。