Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/347.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java继承:为什么引用超类变量_Java - Fatal编程技术网

Java继承:为什么引用超类变量

Java继承:为什么引用超类变量,java,Java,我有一个超级班“Sam”和一个子班“SubSam” 输出为: A B 为什么“toString()”引用的是“Sam”的实例字段而不是“SubSam”。输出应该是:A C 我已经考虑了很长一段时间了,但是没有得到什么?,因为Java中的实例变量并没有被覆盖,非常简单。一个子类可以定义一个与它的一个超类中定义的变量同名的变量,但在所有意图和目的中,它都算作一个单独的变量 例如,考虑下面的代码: public class A { public String var; } public

我有一个超级班“Sam”和一个子班“SubSam”

输出为:

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
方法时该名称就是这样解析的。