java 实例方法和变量的继承解析

发布于 2024-08-09 23:17:00 字数 1178 浏览 5 评论 0原文

根据 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";
    }
}

As per java, instance method resolution is based on runtime types of the arguments.

But while resolving instance variable it uses different approach as shown below.

Output of program is ..

Child
Parent
ParentNonStatic

Here First output is based on runtime types of the argument but third output is not.

can any one explain about this ?

  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";
    }
}

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

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

发布评论

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

评论(3

对你而言 2024-08-16 23:17:00

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

当您向上转换 c 并引用 foo 时,您并不是在进行函数调用。编译器可以在编译时确定您所引用的内容。在本例中,为类型为parent 的对象的字段foo。字段和静态字段不会被覆盖。相反,它们是隐藏的。您实际上最终对这种向上转换所做的事情是帮助 Java 选择隐藏版本(来自父级的版本)而不是来自子级的版本。类似地,使用 hoo 您可以获得父级的版本。

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

When you upcast an object, you don't actually change the content of the item you are referring to, just the way you treat it. So when you upcast c to parent and call please(), you invoke please() on a Parent, but the dynamic type is still a child, so what really gets invoked is the overridden version in child and "Child" is printed.

When you upcast c and refer to foo, you are not making a function call. The compiler can determine at compile time what you are referring to. In this case, the field foo of an object that has the type parent. Fields and static fields are not overridden. Instead, they are hidden. What you actually end up doing with this upcast is helping Java pick the hidden version (the one from Parent) rather than the one from child. Similarly, with hoo you get the version of the parent.

Here's some info from the JAva tutorial: http://java.sun.com/docs/books/tutorial/java/IandI/hidevariables.html

超可爱的懒熊 2024-08-16 23:17:00

在 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对方法进行动态绑定,对字段进行静态绑定。

In Java you don't actually "cast". Java doesn't actually do anything when you ask for a cast except to check if the object can be cast to that type thus why casts can throw a "ClassCastException".

The compiler though understands casts and thus uses them to validate that method calls are appropriate.

With respect to static fields, the compiler in fact removes any instance variables and references the field via the class according whatever the return type is.

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

Fields seem to work the same way.

I think in a nutshell that java does dynamic binding on methods and static binding on fields.

奈何桥上唱咆哮 2024-08-16 23:17:00

字段不会像方法一样被重写。通过将 c 转换为 Parent,您表明“.hoo”引用 Parent 上的“hoo”字段,而不是 Child 上的“hoo”字段。 (用技术上更正确的方式来说,字段访问不是多态的。)

Fields aren't overridden in the same way methods are. By casting c to Parent, you're indicating that ".hoo" refers to the "hoo" field on Parent, not the one on Child. (To put it in a more technically correct way, field access isn't polymorphic.)

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