in this code at Animal a1 = (Hound) o1; gives an exception, because a Canine is not a Hound.
but Animal a1 = (Animal) or (Mammal) or (Canine) o1; won't give an exception. We created a Canine, which IS-AN Animal and IS-A Mammal and IS-A Canine.
Remember - whatever you create, that is what you really have. Casting doesn't change the object type, it just lets you use a different reference type - but the reference type must be valid.
There are only two hard things in computer science: cache invalidation, naming things, and off-by-one errors