Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What does Base b2 = new Child(); signify?

 class Base {

    public void add() {
        System.out.println("Base ADD");
    }

    void subtract() {
        throw new UnsupportedOperationException("Not yet implemented");
    }

}

class Child extends Base {

    public void add(){
        System.out.println("Child ADD");
    }

    public void subtract() {
        System.out.println("Child Subtract");
    }

}

class MainClass {

    public static void main(String args[]) {

        Base b1 = new Base();
        Base b2 = new Child();

        Child b3 = new Child();

        b1.add();

        b2.subtract();  

        b2.add();
        b3.subtract();

    }

}

I am somewhat confused with the above code. The line most confusing me is

Base b2 = new Child();

and

 b2.subtract();

What I understand is at compile time compiler checks weather Base class has subtract() method or not, then at runtime runtime polymorphism occurs as object is of type Child.

The question is how or where we can use this line i.e. Base b2 = new Child();

In what scenario we should use this? Please help, it would be great!

like image 471
Ashish Agarwal Avatar asked Dec 13 '22 17:12

Ashish Agarwal


2 Answers

Look at the two parts of the statement:

Base b2

that declares a variable called b2 of type Base. You can assign a reference to that 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 reference returned by the constructor to the b2 variable.

Now, you can only "see" members of Base through b2, even though the actual value refers to an instance of Child at execution time. But any methods from Base which have been overridden in Child will use the overridden version when they're called... so when you call

b2.subtract();

the JVM finds out the actual type of the object that b2 refers to, and uses that class's implementation of subtract - in this case, the method which prints "Child Subtract".

EDIT: You've specifically asked where you can use this sort of thing, and how it helps...

You can use it any time you want to declare a variable of a more general type (a superclass or an interface) but assign a value to it which happens to be a subclass or an 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're retaining flexibility - later on you could change from using ArrayList<T> to some other implementation of List<T>, and the code should still work. You're basically saying, "I only need the members and guarantees provided by List<T> - the fact that I'm using ArrayList<T> is somewhat incidental."

A similar example is deciding what type a method should return - often you want to only declare that you return a general type (or interface) even though the implementation knows which concrete type it's returning. That hides the implementation details, which allows you to change them later.

like image 161
Jon Skeet Avatar answered Dec 23 '22 22:12

Jon Skeet


Base b2 = new Child(); 

You can use Reference of Super for object of child.

for b2.method();

at compile time you must have method(); in BaseClass.

At run time the Object's method will get invoked so here object is Child from Base b2 = new Child();

So child's method() version will get executed.

Usage:

Polymorphism is extremely useful in designing enterprise-level systems, as you can create and define multiple interface layers that allow outside parties or outside software to interact with your system in a particular way. We all know how helpful it is in system integration to have a published API, but if interior system changes become necessary, the API may have to be republished and integrated systems may have to be reworked. To avoid this, careful consideration should be given to object APIs as well as the overall system APIs during design. One way to ensure that a robust system can deal with objects that have more complex methodologies than were originally intended is to have the object API be polymorphic. This way, the system knows a "face" of the object being passed to it, but doesn't have to be aware of extemporaneous changes.

Also see

  • Standard Docs on Polymorphism
  • Resource
like image 40
jmj Avatar answered Dec 23 '22 23:12

jmj