You only cast an object to some type, if 2 conditions are met:
- you know it is of that type
- the compiler doesn't
This means not all the information you have is well represented in the type structure you use. This is bad, because your implementation should semantically comprise your model, which it clearly doesn't in this case.
Now when you do a cast, then this can have 2 different reasons:
- You did a bad job in expressing the type relationships.
- the languages type system simply is not expressive enough to phrase them.
In most languages you run into the 2nd situation a lot of times. Generics as in Java help a bit, the C++ template system even more, but it is hard to master and even then some things may be impossible or just not worth the effort.
So you could say, a cast is a dirty hack to circumvent your problems to express some specific type relationship in some specific language. Dirty hacks should be avoided. But you can never live without them.