Polymorphism in Java is the ability to create member functions or fields that behaves differently in different programmatic contexts. It is one of the major building blocks of object-oriented programming, along with inheritance, abstraction and encapsulation.
1. What is Polymorphism?
Polymorphism allows a class to act differently in different contexts. We can relate the polymorphism with one interface having multiple implementations. Though the contract defined by the interface remains the same, each class implements the contract differently and thus exhibits different behavior. This is polymorphic behavior.
For example, polymorphism is also referring the instance of a subclass, with a reference variable of the superclass.
Object o = new Object(); //o can hold the reference of any subtype
Object o = new String();
Object o = new Integer();
Here, String and Integer classes are the subclasses of the Object class.
2. Types of Polymorphism
In Java language, polymorphism is essentially considered into two forms:
- Compile time polymorphism (static binding or method overloading)
- Runtime polymorphism (dynamic binding or method overriding)
Here, it is important to understand that these divisions are specific to java. In the context of software engineering, there are other forms of polymorphisms also applicable to different languages, but for java, these two are mainly considered.
2.1. Compile Time Polymorphism
As the meaning is implicit, in compile time polymorphism, the flow of control is decided in compile time itself. It is achieved using method overloading.
In method overloading, an object can have two or more methods with the same name, but the method parameters are different such that:
- number of parameters are different
- method parameter types are different
For example, in the Calculator class, we can have multiple methods with different argument types:
public class Calculator {
public Integer sum(Integer a, Integer b) {
return a + b;
}
public Float sum(Float a, Float b) {
return a + b;
}
public Double sum(Double a, Double b) {
return a + b;
}
}
With the above class definition, when we invoke the sum() method in the program, based on argument types, the compiler decides which method to call on the compile time only, and generates the bytecode accordingly. This is called compile-time polymorphism.
Calculator calc = new Calculator();
Integer sum1 = calc.sum(1 ,2);
Float sum2 = calc.sum(1f ,2f);
Double sum3 = calc.sum(1d ,2d);
2.2. Runtime Polymorphism
Runtime polymorphism is essentially referred as method overriding when we extend a class into a child class. In runtime polymorphism, which method will be invoked is decided on the runtime based on the actual instance of the child class.
A simple example from real-world can animals. An application can have Animal class, and its specialized subclasses like Cat and Dog. These subclasses will override the default behavior provided by Animal class, and additionally, some of its own specific behavior.
class Animal {
public void makeNoise() {
System.out.println("Some sound");
}
}
class Dog extends Animal {
public void makeNoise() {
System.out.println("Bark");
}
}
class Cat extends Animal {
public void makeNoise() {
System.out.println("Meawoo");
}
}
Now when we invoke the makeNoise() method, the method called depends on type of actual instance created on runtime.
Animal cat = new Cat();
cat.makeNoise(); //Prints Meowoo
Animal dog = new Dog();
dog.makeNoise(); //Prints Bark
3. Conclusion
- Polymorphism is the ability to create a variable, function, or object with more than one form.
- In java, polymorphism is divided into method overloading and method overriding.
- Another term, operator overloading, is also there. For example, the “+” operator can be used to add two integers as well as concat two sub-strings. Well, this is the only available support for operator overloading in java, and you can not have your own custom-defined operator overloading in java.
Happy Learning !!
class Animal { int id=10; public void makeNoise() { System.out.println("Some sound"); } } class Dog extends Animal{ int id=20; public void makeNoise() { System.out.println("Bark"); } } class Cat extends Animal{ int id=30; public void makeNoise() { System.out.println("Meawoo"); } } public class OverridingClassConcepts { public static void main(String[] args) { // TODO Auto-generated method stub Animal a1 = new Cat(); a1.makeNoise(); //Prints Meowoo System.out.println(a1.id); // prints 10 // reference type is Animal and object Cat class so its called Cat class method but why its calling Animal class variable.. // why its printing Animal class variable and Catclass method. Animal a2 = new Dog(); a2.makeNoise(); //Prints Bark System.out.println(a2.id); // print 10 //reference type is Animal and object Dog class so its called Dog class method but why its calling Animal class variable.. // why its printing Animal class variable and Dog class method. } }I understand its not completely related to polymorphism concept but please solve my problem
I think you have not gone through the Inheritance concept properly. If you go through the point 3-Accessing inherited parent class members.
“java fields cannot be overridden”. Having same name field will hide the field from parent class – while accessing via child class. Attribute accessed will be decided based on the class of reference type.
But in the case of methods access its opposite to field access. Method access uses the type of actual object created in Run Time.
Hi Pankaj,
To add few things
change the return type or access specifier/modifier in method overloading is not allowed and leads to compiler time error i hope but the same works in method overriding some time called as covariant return type.
overriding with different return type and access specifer
Object Class
protected native Object clone() throws CloneNotSupportedException{
}
User Class
public User clone(){
}
Hi,
Overriding a static method is some time also refer as masking or hiding
can u please explain more about the above points ?
if you write main method in public class Car from there call main method of mini which is non public.????
always it should call the method which object is created right ?? but why here the parent method object is called..???
Consider the below example
public class Parent {
public static void method(){
System.out.println(“parent method is called”);
}
/**
* @param args
*/
public static void main(String[] args) {
Parent p=new Child();
p.method();
}
}
public class Child extends Parent {
public static void method(){
System.out.println(“parent method is called”);
}
}
Output is : parent method is called.
According to above explanations, it should call Child method right..?? why is it calling parent method..??
Sorry , i donno how to edit the comment in the above code…
a small correction…in the above code..
public class Child extends Parent {
public static void method(){
System.out.println(“child method is called”);
}
}
The reason is that static methods are always called for reference type, and not from actual instance. If you look at eclipse warning (“a yellow triangle”), it also hints “The static method method() from the type Parent should be accessed in a static way”.
Also Saurabh pointed out that “static method are not available for method overriding.It is part of class rather than object. But you can always overload Static method.”
Actually there is no difference between below both statements:
1) p.method();
2) Parent.method(); //Both are same
public class Parent
{
public static void method()
{
System.out.println("parent method is called");
}
public void method1()
{
System.out.println("parent method1 is called");
}
public static void main(String[] args)
{
Parent p = new Child();
p.method();
Parent.method();
p.method1(); //A call to non-static method will call method from actual instance
}
}
public class Child extends Parent
{
public static void method()
{
System.out.println("child method is called");
}
public void method1()
{
System.out.println("child method1 is called");
}
}
Let me know if there are more confusions.
Lokesh,
Wondering why someone will create Animal class as per your example. if Amimal class has no use at all. better it should be interface then a Class to force concreat class to implement
or the same method of base class gives different output would have been better example.
I respectfully disagree. As a general rule, you should create classes for nouns and interfaces for verbs i.e. actions. So, actually Animal should be a class with default behavior which all animals will have e.g. that all can move, make noise, eat and many things like that. There is no need to override every behavior for all animals. It will be code duplication. Each animal can override it’s specific behavior only. With interface it is not possible.
Interface which can make sense are Walkable, Swimmable or Fyable which a group of animals can implement based on needs. But still they waill have all default behavior from Animal.class.
Hi Lokesh,
Why JVM call always Overloaded method if i pass null ?
class MyClass {
public void test(Object o) {
System.out.println(“From() method “);
}
public void test(String o) {
System.out.println(“From Overloaded test() method “);
}
}
public class Demo {
public static void main(String[] args) {
MyClass m = new MyClass();
m.test(null);
}
}
O/P= From Overloaded test() method
While resolving the overloaded method to call, JVM tries to find method with most specialized type. NULL can be referred from spring as well as object type variables. But, String is more specialized. So, JVM chooses to call “public void test(String o)”.
I will recommend reading following thread: https://stackoverflow.com/questions/13041042/using-null-in-overloaded-methods-in-java
Hi Praveen,
More fun happens when you also add this
public void test(Integer o) {
System.out.println(“From() method “);
}
Why method overloading happens at compile time only not at run time?please reply
At compile time, JVM generates the bytecode for a program i.e. your class. This bytecode is essentially a sequence of operations. These operations are in low level languages and are executed in sequence.
In case overloading, JVM is able to and it determines which method call it needs to make for a certain operation, so it generates the bytecode equivalent to method call in compile time itself.
In case of overriding, it is unable to determine this so it generates code with certain conditional keywords which determine the actual method call when bytecode runs on machine.
I Guess Nitya’s question is “Why method overloading happens at run time only why not at compile time “?
Compiler dose not know which method is called at compilation time, because Objects are created at the time of Running program. So JVM knows based on the object creation, which method has to call at the time of running the program..
NO. Nitya is right. Overloading is resolved at compile time itself. Overriding is resolved on runtime because actual instance is resolved in runtime time only. Remember, in java super class reference can point to instances of child classes also. Actual instance is resolved at runtime only.