Question

I don't understand how exactly it works.

We have two class A and B. Class B extends A. Class A have x attribute, and test method which modify this attribute. Class B have x attribute, and test method which modify this attribute.

public class A {

    int x;

    public void test() {
         this.x = 1;
        System.out.println("A" + getX());
    }
    int getX() {return x;}
}

public class B extends A {

    int x;

    public void test() {
        this.x = 2;
        System.out.println("B" + getX());
    }
    int getX() {return x;}

}

public class Main {

    public static void main(String[] args) {

        A a = new A();
        a.test();
        System.out.println(a.getX());

        System.out.println("point 1");
        a = new B();
        a.test();
        System.out.println(a.x);
       }
}

Output:

 A1
 1
 point 1
 B2
 0

My prediction about last line of output was 2, but is 0. Why is 0?

Was it helpful?

Solution

Let's understand these lines of code:

a = new B();
a.test();
System.out.println(a.x);
  • You create a new object of B. It will re-initialize the variable - A.x = 0 and B.x = 0.
  • Then you invoke a.test(), which will call the overridden method test() in class B, which will set B.x to 2 using this.x = 2;. Note at this point, A.x is still 0.
  • Then you access a.x, which will access the field x in class A. The fields are not polymorphic. You don't override fields, but you hide them. The variable x in B hides the variable x in A.

OTHER TIPS

If both A and B have a member named x, the one in B will block access to the one inherited from A. Remove the int x; declaration from B, or explicitly use super.x, if you want to reference the one in the parent class.

Starting from begin.

When you write

A a;

You say to JVM please reserve me in memory an address for something that fits A.

after when you do

a = new A();

You say to JVM, create a new object of class A and save the address to it under a

when you do this;

a.test();

You say to JVM, go to memory address a and from object there invoke method test().

Next thing what you do is this:

a = new B();

You say to JVM, create a new object of class B and save the address to it under a. No error here as B fits A as is a child class.

(You loose the connection with object of class A ass you changed it to B).

next operation is

a.test();

you also know this, but this time under address a is instance of class B. This time JVM search for the method in class B, if not fond then will search in class A.

I think you should start over with the Inheritance/Polymorphism concepts first. But to make it clear: You have an object "a" which is declared as with type "A". Now, when you call the method test (which is overriden inside B in this case), the JVM calls the actual objects method. So, before "point 1" a.test calls A's test method, after "point1" it calls B's test method. The problem is that this feature (called polymorphism) works only on methods. Whilst when you call an instance variable (as a.x) , the JVM calls the declared object variable. In this case is A. If you make a cast first, you'll get the right value: ((B)a).x Note, the difference between actual and declared object is based on the type after the "new" operator (like new B()) and that in the object declaration

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top