First, you should get a clear idea of ββthings. Expression of your example: Object obj = new MyClass(); actually a combination of two elementary operations.
The first creates an instance of MyClass: new MyClass() . The new keyword is basically the only way to get an instance of the class (allowing you to ignore reflection at runtime to make it simple), and you literally call what you want to create (MyClass) here as your constructor. It is impossible to create anything other than what you literally called a new keyword. The result of the new is an (implicit) instance of MyClass, but the explicit result of new X is a reference of type X (the reference refers to a newly created instance).
Now the second operation assigns a link to your (new) MyObject to another link of type Object. And this is true because MyObject is an object (due to inheritance).
Why do you need this?
This is an important function that actually uses polymorphism. The ability to refer to any child class as its superclass is what makes polymorphism so powerful. You will mainly use it wherever there is a common aspect for the two classes, but there are differences.
An example of the real world is graphical user interfaces. The window has buttons, lists, tables and panels that are elements of the user interface, but each one does a different thing. To present them neatly organized in a window, these elements are often inserted into panels that talk more abstractly into containers. Now the container does not care what elements are included in it, if they are components. But for the proper handling of the container, some basic information about these components is needed, mainly how much space they take and how to draw them. So this is modeled something like:
public abstract class Component { public int getWidth() { ... } public int getHeight() { ... } public void paint(Graphics g) { ... } } public class Container extends Component { public void add(Component child) { ... } public void paint(Graphics g) { for (Component child : children) { child.paint(g); } } }
What came almost directly from the JDK, the fact is that if you need to refer to each component as its specific type, it would be inappropriate to create a container, this will require additional code for each component that you decide to make (for example, addButton, addTable, etc.). Therefore, instead, Container only works with reference to Component. Regardless of which component is created (e.g. Button, CheckBox, RadioButton, etc.), since the Container just relies on them to be components, they can handle them.