1

我有一个超类“Sam”和一个子类“SubSam”

 public class Sam {

String msg;
String msg1;

Sam(String mm, String mm1) {
    msg = mm;
    msg1 = mm1;
}

@Override
public String toString() {
    return this.msg + "  " + this.msg1;
    }
}

class SubSam extends Sam {

String msg1="C";

public static void main(String[] args) throws Exception {
    SubSam obj = new SubSam();
    System.out.println(obj);
}

SubSam() {
    super("A", "B");
}
}

输出是:

A  B

为什么“toString()”指的是“Sam”的实例字段而不是“SubSam”。输出应为:AC

想了很久,还是没搞定?

4

3 回答 3

4

因为 Java 中的实例变量没有被覆盖,很简单。子类可以定义一个与其超类之一中定义的变量同名的变量,但对于所有意图和目的,它都算作一个单独的变量。

例如,考虑以下代码:

public class A {
    public String var;
}

public class B extends A {
    public int var;
}

给定这些定义,实例B将有两个变量,一个是 type String,另一个是 type 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());,它将打印A C

于 2012-12-09T18:34:48.590 回答
1

您没有覆盖 toString,因此调用了超类的 toString 方法。它打印超类的 msg 和 msg1,而不是子类。

于 2012-12-09T18:36:11.690 回答
0

msg1在子类中设置,但在它的构造函数中您正在传递

super("A","B");

此时,在主类的构造函数中初始化的super变量是使用this关键字intoString方法使用的主类变量。

于 2012-12-09T18:39:34.767 回答