I can see that the term "upcast" is related to OOP, but I can't find the exact definition by searching the Internet.
Could anyone explain what does the term mean and in what situation this technique useful?
From the description of the tag you posted:
Upcasting permits an object of a subclass type to be treated as an object of any superclass type.
Basically, it's where you cast a subclass instance to one of its superclasses, to show an example in pseudocode
class Base {
function say_hi() { printf("Hello From Base Class\n"); }
}
class Person extends Base {
function say_hi() { printf("Hello!"); } // Overridden. Java expects an @Override annotation
}
class Dog extends Base {
function say_hi() { printf("Woof!"); } // Again, overridden
}
Base B = new Base();
Base P = new Person(); // Implicit upcast
Dog dog = new Dog();
Base D = (Base)Dog(); // Explicit upcast
B.say_hi(); // Hello from base class
P.say_hi(); // Hello!
D.say_hi(); // Woof!
There are a variety of times when this is useful. In general, it defines an interface of sorts, so you can subclass something, yet still use it in its original context. Say you have a game, you'd have an enemy object. This has some common functionality, like its current position, speed, health, and other things. Despite this, some enemies might move differently, might play a different die animation, and of course, would be drawn differently. The issue is, since they have the same interface, you don't want to have to have special code to handle every different type of enemy.
It would make sense to make a base "Enemy" class with these fields and empty methods, but then extend it to have SmallEnemy, EvilEnemy, BossEnemy etc with their different models and animations, filling in the blank methods. These "blank" methods can also be referred to as abstract or pure methods.