At very first, I would like to correct you at this line..
I am sure the code is correct.
No, the code is not correct.
I've tried explaining your code step by step, with concepts as comments in code.
public static void main(String [] args)
{
c1 a; // this is just a reference of Type 'c1', holding nothing.
a = new c2(); // assigned new Object of Type 'c2', perfectly fine, no issues with polymorphism.
/* but here,
c2 has value of 'x' as 20;
but when if you use the reference of 'a' (which is of type c1), i.e. 'c1.x' then JVM follows the reference.
Meaning to say is, it will go to class 'c1' and print it's value of 'x' which is 10 & you are getting the same.
*/
System.out.println((long)a.x); //This works and output is 10.
/*
your code, (c2)a.x
Now, Problem starts here,
'a.x' is of type 'int', and you are casting this 'int' to type 'c2',
you will have to convert the reference of 'a' to 'c2'
(i.e 'a' of type 'c1' to 'a' of type 'c2', not 'a.x' to type of 'c2').
So the solution would be, ((c2)a) <---- this is now of type 'c2', now access it's member 'x', it will show you value 20.
*/
System.out.println((c2)a.x); //Error is here
}
You should read these two answers related to casting in java.
1) https://stackoverflow.com/a/30776990
2) https://stackoverflow.com/a/1302612