Try to understand from the memory angle of the object.
Suppose that there is now a parent class father, the variables inside it need to occupy 1 m of memory. There is a subclass of it that has a variable that takes up 0.5M of memory.
Now let's look at the allocation of memory by code:
Father f = new Father (); The system allocates 1 m of memory.
Son s = new Son (); The system will allocate 1.5M of memory! Because a hidden reference in a subclass super points to the parent class instance, a parent class is instantiated before the subclass is instantiated, that is, the constructor of the parent class is executed first. Because s contains an instance of the parent class, S can call methods of the parent class.
Son S1 = s; The S1 points to the 1.5M of memory.
Father f1 = (Father) s; At this point the F1 points to 1 m of memory in 1.5M memory, that is, F1 only points to the parent instance object of the instance in S, so F1 can only invoke the method of the parent class (stored in 1 m memory) and cannot call the method of the subclass (stored in 0.5M memory).
Son s2 = (son) F; This code will be reported classcastexception when run. Because there is only 1 m of memory in F, references to subclasses must have 1.5M of memory, so they cannot be converted.
Son s3 = (son) F1; This sentence can be run, then S3 point to that 1.5M of memory. Since F1 is converted by S, it has 1.5M of memory, but it only points to 1 m of memory.
"Go" Java Parent class and child class memory references explained