Consider:
class TestParent{
public int i = 100;
public void printName(){
System.err.println(this); //{TestChild@428} according to the Debugger.
Syste
What's happening here is that there are two completely different fields both called i; to use their full names, one is TestParent::i and one is TestChild::i.
Because the method printName is defined in TestParent, when it refers to i, it can only see TestParent::i, which is set to 100.
Whereas when you set i to 200 in TestChild, both fields called i are visible, but because they have the same name, TestChild::i hides TestParent::i, and you end up setting TestChild::i and leaving TestParent::i untouched.