Look at the two parts of the statement:
Base b2
which declares a variable of type b2 type Base . You can assign a reference to this variable if the reference is null or refers to an instance of Base or a subclass of Base .
Then
new Child()
creates a new instance of Child . Child is a subclass of Base , so you can assign the link returned by the constructor to b2 .
Now you can only see Base members through b2 , although the actual value refers to the Child instance at run time. But any methods from Base that were overridden in Child will use the overridden version when they are called ... so when you call
b2.subtract();
The JVM detects the actual type of object that b2 belongs to, and uses this implementation of the subtract class - in this case, the method that prints "Child Subtract".
EDIT: You specifically asked where you can use such things, and how that helps ...
You can use it anytime you want to declare a variable of a more general type (superclass or interface), but assign a value to it, which is a subclass or implementation of the interface. As another example:
List<String> strings = new ArrayList<String>();
The main advantage of declaring a variable in a general way is that you remain flexible - later you can switch from using ArrayList<T> to some other implementation of List<T> , and the code should still work. You basically say: "I only need the members and guarantees provided by List<T> - the fact that I use ArrayList<T> is somewhat random."
A similar example is the choice of the type of the returned method - often you want to declare that you are returning a generic type (or interface), although the implementation knows which concrete type it returns. This hides implementation details that allow you to modify them later.
source share