71

When I started to look for the benefits of polymorphism, I found with this question here. But here I was unable to find my answer. Let me tell what I want to find. Here I have some classes:

class CoolingMachines{
    public void startMachine(){
        //No implementationion
    }
    public void stopMachine(){
        //No implementationion
    }
}

class Refrigerator extends CoolingMachines{
    public void startMachine(){
        System.out.println("Refrigerator Starts");
    }
    public void stopMachine(){
        System.out.println("Refrigerator Stop");
    }
    public void trip(){
        System.out.println("Refrigerator Trip");
    }
}

class AirConditioner extends CoolingMachines{
    public void startMachine(){
        System.out.println("AC Starts");
    }
    public void stopMachine(){
        System.out.println("AC Stop");
    }
}

public class PolymorphismDemo {
    CoolingMachines cm = new Refrigerator();
    Refrigerator rf = new Refrigerator();
}

Now here I created two objects in the Demo class and are references of Refrigerator. I have completely understood that from the rf object I am able to call the trip() method of Refrigerator, but that method will be hidden for the cm object. Now my question is why should I use polymorphism or why should I use

CoolingMachines cm = new Refrigerator();

when I am OK with

Refrigerator rf = new Refrigerator();

Is polymorphic object's efficiency is good or light in weight? What is the basic purpose and difference between both of these objects? Is there any difference between cm.start(); and rf.start()?

Community
  • 1
  • 1
khan
  • 2,664
  • 8
  • 38
  • 64

9 Answers9

73

It is useful when you handle lists... A short example:

List<CoolingMachines> coolingMachines = ... // a list of CoolingMachines 
for (CoolingMachine current : coolingMachines) {
    current.start();
}

Or when you want to allow a method to work with any subclass of CoolingMachines

Ruan Mendes
  • 90,375
  • 31
  • 153
  • 217
pgras
  • 12,614
  • 4
  • 38
  • 46
  • 22
    This is obviously just one example of how it can be useful. Basically, you can have common API. – user606723 Jun 18 '12 at 14:02
  • 1
    Yeah, this is definitely only one example. For a more conceptual understanding it's better when designing an application that is scalable, readable, and may follow design patters (useful when designing class diagrams). – Donnie Jun 18 '12 at 17:51
  • 1
    It is also designed to obey the Liskov Substitution Principle: The principle states that if `S` is a subtype of `T`, THEN `T` could be substituted for every occurance of `S` – Shehaaz Apr 29 '13 at 00:25
58

In cases where you're really okay with knowing the concrete class, there's no benefit. However, in many cases you want to be able to write code which only knows about the base class or interface.

For example, look at Iterables in Guava - that's a lot of methods which (mostly) don't care what implementation of Iterable is being used. Would you really want all that code separately for every implementation?

Where you can code to an abstract base class or an interface, you allow yourself to later use other implementations which share the same public API, but may have different implementations. Even if you only want a single production implementation, you may well want alternative implementations for testing. (The extent to which this applies very much depends on the class in question.)

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • 4
    This then let's us start using things like Dependency Injection, for example. Interface based programming has a huge number of advantages. – jcolebrand Jun 18 '12 at 16:17
  • 4
    @jcolebrand, like testing against interfaces, instead of implementation. Then your unit tests don't care whether the data is being pulled from a database, flat file, or thin air. Integration tests should, but that's a different story ;) – Wayne Werner Jun 18 '12 at 16:22
31

Because later if you want to use AirConditioner instead of Refrigerator for cooling, then only code you need to change is CoolingMachines cm = new AirConditioner();

Naveen
  • 74,600
  • 47
  • 176
  • 233
17

The reason that you want to use

CoolingMachines cm = new Refrigerator();

is that you can later easily use a different CoolingMachines. You only need to change that one line of code and the rest of the code will still work (as it will only use methods of CoolingMachines, which is more general than a specific machine, such as a Refrigerator).

So for a particular instance of Refrigerator, the calls cm.start(); and rf.start() work the same way but cm might also be a different CoolingMachines object. And that object could have a different implementation of start().

Simeon Visser
  • 118,920
  • 18
  • 185
  • 180
7

First answer:

Use polymorphism for method overridding and method overloading. Other class methods used in different class then two options: first method inherited, second method over written. Here extend interface: use them, or implemention method: logic write them. Polymorphism used for method, class inheritance.

Second answer:

Is there any difference between cm.start(); and rf.start();?

Yes, both are objects that are completely different with respect to each other. Do not create interface objects because Java doesn`t support interface objects. First object created for interface and second for Refrigerator class. Second object right now.

jcolebrand
  • 15,889
  • 12
  • 75
  • 121
Solomon Bindavid
  • 83
  • 1
  • 1
  • 6
  • 7
    Let me introduce you to two of my closest friends, `Shift` and `Enter`. Welcome to our community, but here we like to format things, rather than just keep typing blindly. Also, I need you to review the changes I made and ensure that they kept the intent of your post. Feel free to edit. I think you made _some_ errors in your statements, but I'm not entirely sure. – jcolebrand Jun 18 '12 at 16:19
5

The most general answer to the general part of your question (why should I use polymorphism?) is that polymorphism realizes a few critical object-oriented design principles, for example:

  • code reuse: By putting any code that is common to all of your 'cooling-machines' into cooling-machine, you only need to write that code once and any edits to that code trickle down instantly.

  • abstraction: Human brains can only keep track of so much stuff, but they are good at categories and hierarchies. This helps understand what's happening in a big program.

  • encapsulation: each class hides the details of what it's doing and just builds on the interface of the base class.

  • separation of concerns: a lot of object oriented programming is about assigning responsibilities. Who is going to be in charge of that? Specialized concerns can go in subclasses.

So polymorphism is just part of the bigger oo picture, and the reasons for using it sometimes only make sense if you are going to try and do 'real' oo programming.

Scruffy
  • 908
  • 1
  • 8
  • 21
4

A simple use case of polymorphism is that you can have an array of coolingMachines where element 0 is a refrigator and element 1 is an AirConditioner etc...

You do not need to preform any checks or make sure which object you are dealing with in order to call trip or start etc.

This can be a great benefit when taking input from a user and having to iterate over all the objects and call similar functions

Simon McLoughlin
  • 8,293
  • 5
  • 32
  • 56
2

Using your objects polymorphically also helps to create factories or families of related classes which is an important part of how Factory Design Pattern is implemented. Here's a very basic example of polymorphic factory:

public CoolingMachine CreateCoolingMachines(string machineType)
{
    if(machineType == "ref")
        return new Refrigerator();
    //other else ifs to return other types of CoolingMachine family
}

usage of calling above code:

CoolingMachine cm = CreateCoolingMachine("AC"); //the cm variable will have a reference to Airconditioner class which is returned by CreateCoolingMachines() method polymorphically

Also, imagine that you have a method as below that uses concrete class parameter Refrigerator:

public void UseObject(Refrigerator refObject)
{
    //Implementation to use Refrigerator object only
}

Now, if you change above implementation of UseObject() method to use most generic base class parameter, the calling code would get advantage to pass any parameter polymorphically which can then be utilized inside the method UseObject():

public void UseObject(CoolingMachine coolingMachineObject)
{
    //Implementation to use Generic object and all derived objects
}

Above code is now more extensible as other subclasses could be added later to the family of CoolingMachines, and objects of those new subclasses would also work with the existing code.

S2S2
  • 8,322
  • 5
  • 37
  • 65
  • 3
    I think you got part of your explanation backwards. One uses factories as a means to allow for polymorphic code, not as an end for polymorphic code. – hugomg Jun 18 '12 at 15:38
  • 2
    I agree with missingo, Factories are simply a hack for dealing with the restrictions put into place by modern OOP languages like Java and C#. – Timothy Baldridge Jun 18 '12 at 18:33
  • @missingno that is what also I am trying to say, Factories make use of Polymorphic code but there are other requirements of polymorphic code also.. – S2S2 Jun 19 '12 at 04:39
2

I'll give an easy to understand example. Lets say you have some json

{"a":[1,2],"sz":"text", "v":3, "f":1.2}

Now lets say programmatically you want to list the name, type and value. Instead of having a switch() for each type (array for a, string for sz, etc) you can just have a base type and call a function which does its job. It is also more cpu efficient than using a switch with a dozen types.

Then there are plugins, libs and foreign code with interface reasons.