开发者

Question relating to mixing up the overriding of stating and instance variables?

Ttaking the following code, (source):

    class Parent {
    Integer a = 1;
    static Integer b = 2;
}

class Child extends Par开发者_运维知识库ent {
    static Integer a = 41;
    Integer b = 42;
}

public class Test {
    public static void main(String[] args) {
        Parent parent = new Parent();
        Child child = new Child();
        Parent yo = new Child();
        System.out.format("%d %d %d %d %d %d ",
        parent.a,
        parent.b,
        child.a,
        child.b,
        yo.a,
        yo.b);
    }
}

Why is the result of yo.a and yo.b 1 and 2 respectively? I am confused since, yo points to a Child object, it would yield 41 and 2 as the result, since in Parent, a is non-static, thus the subclass's version of a will be printed instead of the superclass version.


Variables (fields) are not overridden, neither instance variables nor class variables.

An object always has all the instance variables from all the superclasses. A class has only the static variables it defines itself, though it also can access the superclasses' (and interfaces') variables (if not private).

If you redefine a variable in a subclass, you are shadowing the original one, i.e. can't directly access it. It is still existent.

Which variable is accessible only depends on the (compile-time) type used to access it, not on the concrete object's class.


There is no dynamic binding for fields, all bindings for fields are done at compile time. That is why , it is printed fields of parent class not child. And also, static modifier does not change any thing, you can remove all static modifier and also you get the same result..

You should keep in mind that, only instance methods are dynamically binded in Java language.


Maybe this modified example helps to clarify the decision on which fields are seen or hidden, based on the compile-time type:

  public static void main(String[] args) {
    Parent parent = new Parent();
    Child child = new Child();
    Parent yo = new Child();
    System.out.println(parent.a + " " + parent.b);
    System.out.println(child.a + " " + child.b);

    // you said it's a Parent
    System.out.println(yo.a + " " + yo.b);

    // but now you're saying it's a child
    System.out.println(((Child)yo).a + " " + ((Child)yo).b);

    // you said Child, but now you're saying it's a Parent
    System.out.println(((Parent)child).a + " " + ((Parent)child).b);
  }

which gives output:

1 2
41 42
1 2
41 42
1 2

The compiler is deciding based on the information you give it.


There is no instance variable a in class Child objects. Or, more precisely, the only instance variable a in Child objects is the one inherited from Parent; class Child does not define its own instance variable named a.


Classes have fields. Instance fields cannot be overridden, only hidden in sub-classes. Local variables cannot be overridden or hidden. Static fields and method are bound to the class and attempting to use an instance variable is misleading because the instance variable is ignored.

e.g.

Parent yo = null;
System.out.println(yo.a); // prints 1

BTW: It is better to use int instead of Integer unless you really need an Integer.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜