After the assignment a = c, both of these variables reference the same object, which is an instance of Horse. However, by assigning the Horse reference to a variable of type Animal, the reference is automatically upcast to type Animal. This is called "assignment conversion."
Now, because the variable "a" is of type Animal, a.weight accesses the weight variable in Animal. And because the variable "c" is of type Horse, c.weight accesses the weight variable in Horse.
But unlike variables, methods can be
overridden. And due to
polymorphism, a.eat() invokes the overridden method body of eat().
See the JavaRanch article,
How my Dog learned Polymorphism.