Hey pani, Since the topic was closed i could not reply to the post, Only admins can re-open a closed topic. Am wondering how was this closed wihtout any solution. Here is my answer to this.
1) In the first program : Super s = new Sub(); System.out.println(s.i);
Here you have a Super class reference refering to a Sub class instance. Since you have a super class reference you can access only Super class members wiht it any attempt to access Sub class members will show an compiler errror. So in System.out,println when you say s.i you are actually refeering to i that is defined in Super class and since Sub class does not have any instance variable with i declared here , There is no confusion and hence the result is 20 because after the super class constructor runs in Sub() the variable i is assigned to 20 and therefore the result is 20. Note: Compiler will insert a call to super() as first statement in child class constructor.
2) Now when you modify Sub to declare i , Now you have to variables i with same name , one in parent class and another in child class, Both of which are different and when you instantiate child class object, child class object will have both the variables "i". Now again coming to main method, You instantiate a child class object 1) So the child class constructor is invoked which will then invoke parent class constructor. 2) Beofer parent class constructor is invoked, compiler will create a instance variable i and intialize it with 10 , And then invoke parent class constructor where i is now assgined a value 30. and then it returns to child class constructor. So now i [ parent class ] will have 30. 3) Child class constructor will create a variable i and assign 20. Both these i variables are different now [EArlier there was only one i variable] 4) Now in println method you are reffering to i, The question is which i? parent class or child class, This is decided @ compile time using the type of the reference and since its of type "Super" the s.i is reffering to i of parent class and not child class, so the result now is 30 and not 20. Hope this clears.
If you two instance variables of same name in child and super class then the variable to which the reference is pointing to is decided @ compile type and depends on the type of the reference. IF the reference is of type Parent class then the parent class variable will be referenced and if the reference is of type Child class then the child class variable will be referenced. IT does not depend on the actual object type.
However with instance methods of same name the situation is excatly opposite [Method overriding] Hope this answers your question. Thanks Deepak