Can you think of an example where an object oriented language without downcasting would be a sever hinderance?
Cat implements Animal, and you can cast Cat to Animal, but you can't cast Animal back to Cat because you can't statically verify at compile time that Animal will be a Cat.
The only example I can think of it is if a container that allows elements of any type, even then I'm sure you could get around it. For example (in psuedocode):
Code:
interface CatOrDog {
void IsCatOrDog(void (*isCat)(Cat *cat), void (*isDog)(Dog *dog));
}
class Cat : CatOrDog {
void IsCatOrDog(void (*isCat)(Cat *cat), void (*isDog)(Dog *dog)) {
isCat(this);
}
}
class Dog : IsCatOrDog {
void DoSomething(void (*isCat)(Cat *cat), void (*isDog)(Dog *dog)) {
isDog(this);
}
}
Container <CatOrDog> containerOfCatsAndDogs;
CatOrDog animal = containerOfCatsAndDogs[0];
animal.IsCatOrDog(void (Cat *cat) {
print("this is a cat");
},
void (Dog *dog) {
print("this is a dog");
});
But, this required modifying Cat and Dog to implement CatOrDog and add a method IsCatOrDog, which if you had a lot of collections of different combinations, you might end up with some really messy code (and in a formal software development environment, your team may not appreciate you adding new methods to other classes). Can you think of another way around this without downcasting?