You are mistaken. That "B" class only has its own field, and does not express the field from the superclass. Let's override your getI() method in B. You do that by putting an identical method in the A class. Now let's look at the bytecode
Look at B.init; this calls A.init (invokespecial #1) and that sets up the field i to 10 with bipush. Then later on you can see it sets the field i to 30. So you actually have two
is. Look at the two getI() methods, which are identical. Now look at the getSuperI() method. You can see it calls a field of another class (A.i) (the :I bit means it's an
int). You have got two separate fields in the two classes. Let's add some lines to your main method
and see what it prints out.
java B
objA's i as an A is: 10
objB's i is : 30
objB's i from its parent is : 10
objAc's i when cast to a B is: 30
objAc's i when not cast to a B is: 10
objAc's i when cast to a B is: 30
objAc's i when not cast to a B is: 30
You see you have two values for
i depending on whether you cast or not. So this isn't an overridden field at all; there are two fields. Look at the overridden method. This gives 30 whether you cast or not. See the difference in behaviour. The method is overridden; the field is hidden.