java inheritance resolution in case of instance methods and variables

爷,独闯天下 提交于 2019-12-22 18:44:09

问题


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

回答1:


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.




回答2:


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




回答3:


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.)



来源:https://stackoverflow.com/questions/1677993/java-inheritance-resolution-in-case-of-instance-methods-and-variables

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!