Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Initialization in polymorphism of variables

Suppose you have the following code

class A {
    int i = 4;

    A() { 
        print();
    }

    void print () {
        System.out.println("A");
    }
}

class B extends A {
    int i = 2;              //"this line"

    public static void main(String[] args){
        A a = new B();
        a.print();
    }

    void print () {
        System.out.println(i);
    }
}

this will print 0 2

Now, if you remove line labeled "this line" the code will print 4 4

  • I understand that if there was no int i=2; line,

A a = new B(); will call class A, initializes i as 4, call constructor,
which gives control over to print() method in class B, and finally prints 4.

a.print() will call print() method in class B because the methods will bind at runtime, which will also use the value defined at class A, 4.

(Of course if there is any mistake in my reasoning, let me know)

  • However, what i don't understand is if there is int i=2.

why is it that if you insert the code, the first part (creating object) will all of sudden print 0 instead of 4? Why does it not initialize the variable as i=4, but instead assigns default value?

like image 685
SERich Avatar asked Sep 26 '16 02:09

SERich


People also ask

What is the initialization of a variable?

Initialization is the process of assigning a value to the Variable. Every programming language has its own method of initializing the variable. If the value is not assigned to the Variable, then the process is only called a Declaration.

What is initialization of variable in Java?

To initialize a variable is to give it a correct initial value. It's so important to do this that Java either initializes a variable for you, or it indicates an error has occurred, telling you to initialize a variable. Most of the times, Java wants you to initialize the variable.

What is initialization method?

The initialize method is useful when we want to initialize some class variables at the time of object creation. The initialize method is part of the object-creation process in Ruby and it allows us to set the initial values for an object. Below are some points about Initialize : We can define default argument.


3 Answers

It is a combination of several behaviors in Java.

  1. Method overriding
  2. Instance variable shadowing
  3. order of constructors

I will simply go through what happened in your code, and see if you understand.

Your code conceptually looks like this (skipping main()):

class A {
    int i = 0; // default value

    A() { 
        A::i = 4;  // originally in initialization statement
        print();
    }

    void print () {
        System.out.println("A");
    }
}

class B extends A {
    int i = 0;              // Remember this shadows A::i

    public B() {
        super();
        B::i = 2;
    }

    void print () {
        System.out.println(i);
    }
}

So, when in your original main(), you called A a = new B();, it is constructing a B, for which this happens:

  • A::i and B::i are all in default value 0
  • super(), which means A's constructor is called
    • A::i is set to 4
    • print() is called. Due to late-binding, it is bound to B::print()
    • B::print() is trying to print out B::i, which which is still 0
  • B::i is set to 2

Then when you call a.print() in your main(), it is bounded to B::print() which is printing out B::i (which is 2 at this moment).

Hence the result you see

like image 159
Adrian Shum Avatar answered Oct 02 '22 16:10

Adrian Shum


All the instance variables in the new object, including those declared in superclasses, are initialized to their default values - JLS 12.5

Therefore, your variable B::i will be initialized to 0. The constructor in B will be like:

B() {
    super();
    i = 2;
}

So when you call

A a = new B();

The constructor in A will call the print method in B, which will prints the i in class B, which is 0.

like image 43
Nier Avatar answered Oct 05 '22 16:10

Nier


In your case the class B, the declaration of "i" hides the declaration of "i" in A, and all references to "i" in the child class refer to the B.i not the A.i.

And so what you see in A.i is the default value of any int attribute in java which is zero.

Java instance variables cannot be overridden in a subclass.

You want to try this for more clarification.

class B extends A {
    int i = 2;              //"this line"

    public static void main(String[] args){
        B b = new B();
        A a = b;
        System.out.println("a.i is " + a.i);
    System.out.println("b.i is " + b.i);
    }

    void print () {
        System.out.println(i);
    }
}

Ouput:

a.i is 4
b.i is 2
like image 27
mhasan Avatar answered Oct 01 '22 16:10

mhasan