为什么不根据其对象的运行时类型来选择此方法?

发布于 2024-08-15 13:43:18 字数 667 浏览 2 评论 0 原文

考虑一下:

class A  {
    int x =5;
}

class B extends A{
        int x =6;
    }
public class CovariantTest {

    public A getObject() {
        return new A();
    }

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        // TODO code application logic here
        CovariantTest c1 = new SubCovariantTest();
        System.out.println(c1.getObject().x);
    }

}

class SubCovariantTest extends CovariantTest {
    public B getObject(){
        return new B();
    }
}

据我所知,JVM 根据其对象的真实类型来选择方法。这里真正的类型是 SubCovariantTest,它定义了一个重写方法 getObject。

程序打印 5,而不是 6。为什么?

Consider this:

class A  {
    int x =5;
}

class B extends A{
        int x =6;
    }
public class CovariantTest {

    public A getObject() {
        return new A();
    }

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        // TODO code application logic here
        CovariantTest c1 = new SubCovariantTest();
        System.out.println(c1.getObject().x);
    }

}

class SubCovariantTest extends CovariantTest {
    public B getObject(){
        return new B();
    }
}

As far as I know, the JVM chooses a method based on the true type of its object. Here the true type is SubCovariantTest, which has defined an overriding method getObject.

The program prints 5, instead of 6. Why?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

往事风中埋 2024-08-22 13:43:18

该方法确实是由对象的运行时类型选择的。运行时类型没有选择的是整数字段 xB 对象存在两个 x 副本,一份用于 Ax,一份用于 Bx。您静态A类中选择字段,作为getObject返回的对象的编译时类型是A。可以通过向 AB 添加方法来验证这一事实:

class A  {
    public String print() {
        return "A";
    }
}

class B extends A {
    public String print() {
        return "B";
    }
}

并将测试表达式更改为:

System.out.println(c1.getObject().print());

The method is indeed chosen by the runtime type of the object. What is not chosen by the runtime type is the integer field x. Two copies of x exist for the B object, one for A.x and one for B.x. You are statically choosing the field from A class, as the compile-time type of the object returned by getObject is A. This fact can be verified by adding a method to A and B:

class A  {
    public String print() {
        return "A";
    }
}

class B extends A {
    public String print() {
        return "B";
    }
}

and changing the test expression to:

System.out.println(c1.getObject().print());
套路撩心 2024-08-22 13:43:18

除非我弄错了,否则默认情况下方法在 java 中是虚拟的,因此您可以正确地覆盖该方法。然而字段(如“x”)不是虚拟的并且不能被覆盖。当您在 B 中声明“int x”时,您实际上是在创建一个全新的变量。

多态性不会对字段生效,因此当您尝试在转换为类型 A 的对象上检索 x 时,您将得到 5,如果该对象转换为类型 B,您将得到 6。

Unless I'm mistaken, methods are virtual in java by default, so you're overriding the method properly. Fields however (like 'x') are not virtual and can't be overriden. When you declare "int x" in B, you are actually creating a totally new variable.

Polymorphism doesn't go into effect for fields, so when you try and retrieve x on an object casted to type A, you will get 5, if the object is casted to type B, you will get 6.

如歌彻婉言 2024-08-22 13:43:18

当超类和子类中的字段具有相同名称时,称为“隐藏”。除了问答中提到的问题之外,还有其他方面可能会引起微妙的问题:

来自 http://java.sun.com/docs/books/tutorial/java/IandI/hidevariables.html

在一个类中,一个字段具有
与超类中的字段同名
隐藏超类的字段,即使
他们的类型不同。内
子类,超类中的字段
不能简单地引用
姓名。相反,该字段必须是
通过 super 访问,即
下一节将介绍。一般来说
说来说去,我们不建议隐藏
字段,因为它使代码难以
阅读。

有些编译器会警告隐藏变量

When fields in super and subclasses have the same names it is referred to as "hiding". Besides the problems mentioned in the question and answer there are other aspects which may give rise to subtle problems:

From http://java.sun.com/docs/books/tutorial/java/IandI/hidevariables.html

Within a class, a field that has the
same name as a field in the superclass
hides the superclass's field, even if
their types are different. Within the
subclass, the field in the superclass
cannot be referenced by its simple
name. Instead, the field must be
accessed through super, which is
covered in the next section. Generally
speaking, we don't recommend hiding
fields as it makes code difficult to
read.

Some compilers will warn against hiding variables

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文