2

根据 java,实例方法解析基于参数的运行时类型。

但是在解析实例变量时,它使用不同的方法,如下所示。

程序的输出是..

Child
Parent
ParentNonStatic

这里第一个输出基于参数的运行时类型,但第三个输出不是。

有人可以解释一下吗?

  public class Child extends Parent {

        public static String foo = "Child";
        public String hoo = "ChildNonStatic";

        private Child() {
            super(1);
        }

        @Override
        String please() {
            return "Child";
        }

        public static void main(String[] args) {
            Parent p = new Parent();
            Child c = new Child();

           //Resolving method
            System.out.println(((Parent) c).please());

           //Resolving Static Variable
            System.out.println(((Parent) c).foo);

           //Resolving Instance Variable
            System.out.println(((Parent) c).hoo);
        }
    }
class Parent {

    public static String foo = "Parent";
    public String hoo = "ParentNonStatic";

    public Parent(int a) {
    }

    public Parent() {
    }

    String please() {
        return "Tree";
    }
}
4

3 回答 3

6

当你向上转换一个对象时,你实际上并没有改变你所指的项目的内容,只是你对待它的方式。因此,当您将 c 向上转换为父级并调用 please() 时,您会在父级上调用 please(),但动态类型仍然是子级,因此真正被调用的是子级中的覆盖版本并打印“子级”。

当您向上转换 c 并引用 foo 时,您并没有进行函数调用。编译器可以在编译时确定您所指的内容。在这种情况下,具有父类型的对象的字段 foo。字段和静态字段不会被覆盖。相反,它们是隐藏的。实际上,您最终对这个 upcast 所做的是帮助 Java 选择隐藏版本(来自 Parent 的那个)而不是来自 child 的那个。同样,使用 hoo 您可以获得父级的版本。

以下是来自 JAva 教程的一些信息:http: //java.sun.com/docs/books/tutorial/java/IandI/hidevariables.html

于 2009-11-05T02:52:00.983 回答
2

在 Java 中,您实际上并没有“强制转换”。当您要求强制转换时, Java 实际上并没有任何事情,只是检查对象是否可以强制转换为该类型,因此强制转换会抛出“ClassCastException”。

编译器虽然理解强制转换,因此使用它们来验证方法调用是否合适。

对于静态字段,编译器实际上删除了任何实例变量,并根据返回类型通过类引用该字段。

Parent p = new Parent();
Child c = new Child(); 
Parent pc = new Child();

System.out.println(c.foo); // will print Child
System.out.println(p.foo); // will print Parent
System.out.println(pc.foo); // will print Parent
System.out.println(((Child)pc).foo) // will print Child

字段似乎以相同的方式工作。

简而言之,我认为java对方法进行动态绑定,对字段进行静态绑定。

于 2009-11-05T13:41:50.820 回答
0

字段不会以与方法相同的方式被覆盖。通过将 c 转换为 Parent,您表明“.hoo”是指 Parent 上的“hoo”字段,而不是 Child 上的字段。(用更技术上正确的方式说,字段访问不是多态的。)

于 2009-11-05T02:45:09.610 回答