Polymorphism in Java
Polymorphism in Java
Polymorphism in Java
Example:
Note:
Ex-:
class Test {
public void m1(double d)
{
}
public void m2(int i)
{
}
public static void main(String ar[]) {
Test t=new Test();
t.m1(10.5);
t.m2(10);
t.m3(10.5); //CE
}
}
Note: - Within the same class we can't take 2 methods with the same signature
otherwise we will get compile time error.
Example:
Note:-
Example 1: We can use same abs() method for int type, long type, float type etc.
Example:
1. abs(int)
2. abs(long)
3. abs(float)
Types of Polymorphism:-
1. Compile-time polymorphism
2. Runtime polymorphism.
3-Pillars of OOPS:-
1) Inheritance talks about reusability.
If a class has multiple methods having same name but different in parameters, it is
known as Method Overloading.
Two methods are said to be overload if and only if both having the same
name but different argument types.
In 'C' language we can't take 2 methods with the same name and different
types.
Example:
Having the same name and different argument types is called method
overloading.
All these methods are considered as overloaded methods.
Having overloading concept in java reduces complexity of the programming.
If we have to perform only one operation, having same name of the methods
increases the readability of the program.
Example:
class Test {
public void m1() {
System.out.println("no-arg method");
}
public void m1(int i) {
System.out.println("int-arg method"); //overloaded methods
}
public void m1(double d) {
System.out.println("double-arg method");
}
public static void main(String[] args) {
Test t=new Test();
t.m1();//no-arg method
t.m1(10);//int-arg method
t.m1(10.5);//double-arg method
}
}
Conclusion: In overloading compiler is responsible to perform method resolution
(decision) based on the reference type (but not based on run time object). Hence
overloading is also considered as compile time polymorphism (or) static
polymorphism (or) early biding.
Note: - In Java, Method Overloading is not possible by changing the return type of
the method only. Means: If two or more method have same name and same
parameter list but differs in return type can not be overloaded
We have created two methods, first add() method performs addition of two
numbers and second add method performs addition of three numbers.
Ex:-
We are creating static methods so that we don't need to create instance for calling
methods.
class Adder{
static int add(int a,int b){
return a+b;
}
static int add(int a,int b,int c){
return a+b+c;
}
}
class TestOverloading1{
public static void main(String[] args){
System.out.println(Adder.add(11,11));
System.out.println(Adder.add(11,11,11));
}}
Output:
22
33
Ex-2:-
class Demo{
void multiply(int l, int b){
System.out.println("Result is"+(l*b)) ;
}
void multiply(int l, int b,int h){
System.out.println("Result is"+(l*b*h));
}
public static void main(String[] args){
Demo ar = new Demo();
ar.multiply(8,5); //multiply(int l, int b) is method is called
ar.multiply(4,6,2); //multiply(int l, int b,int h) is called
}
}
2) Method Overloading: changing data type of arguments
Ex:-
We have created two methods that differs in data type. The first add method
receives two integer arguments and second add method receives two double
arguments.
class Adder{
static int add(int a, int b){
return a+b;
}
static double add(double a, double b){
return a+b;
}
}
class TestOverloading2{
public static void main(String[] args){
System.out.println(Adder.add(11,11));
System.out.println(Adder.add(12.3,12.6));
}}
Output:
22
24.9
Ex-2:-
class Calculate{
void sum (int a, int b){
System.out.println("sum is"+(a+b)) ;
}
void sum (float a, float b){
System.out.println("sum is"+(a+b));
}
Public static void main (String[] args){
Calculate cal = new Calculate();
cal.sum (8,5); //sum(int a, int b) is method is called.
cal.sum (4.6f, 3.8f); //sum(float a, float b) is called.
}
}
Output:
Sum is 13
Sum is 8.4
Q) Why Method Overloading is not possible by changing the return type of
method only?
In java, method overloading is not possible by changing the return type of the
method only because of ambiguity. Let's see how ambiguity may occur:
Ex:-
class Adder{
static int add(int a,int b){
return a+b;
}
static double add(int a,int b){
return a+b;
}
}
class TestOverloading3{
public static void main(String[] args){
System.out.println(Adder.add(11,11));//ambiguity
}}
Output:
Compile Time Error: method add(int,int) is already defined in class Adder
Yes, by method overloading. You can have any number of main methods in a class
by method overloading. But JVM calls main() method which receives string array
as arguments only.
Ex:-
class TestOverloading4{
Output:
Ex:-2
System.out.println(args);
}
public static void main(char args) {
System.out.println(args);
System.out.println(args);
MethodDemo10.main(12);
MethodDemo10.main('c');
MethodDemo10.main(1236);
We can have two methods with same name and parameters but the order of
parameters is different.
Example:
class Demo{
class MethodDemo8{
public static void main (String[] args) {
Demo obj = new Demo();
obj.get("Cherry", 1);
obj.get("Jhon", 2);
}
}
Automatic promotion in overloading.-
byte can be promoted to short, int, long, float or double. The short datatype can be
promoted to int, long, float or double. The char datatype can be promoted to
int,long,float or double and so on.
class OverloadingCalculation1{
void sum(int a,long b){
System.out.println(a+b);
}
If there are matching type arguments in the method, type promotion is not
performed.
class OverloadingCalculation2{
void sum(int a,int b){
System.out.println("int arg method invoked");
}
void sum(long a,long b){
System.out.println("long arg method invoked");
}
class OverloadingCalculation3{
obj.sum(20,20);//now ambiguity
Note: One type is not de-promoted implicitly for example double cannot be
depromoted to any type implicitly.
Below is an example in which you will know how a null value can cause an error
when methods are overloaded.
Example:
Null value is a default value for all the reference types. It created ambiguity to
JVM that reports error.
System.out.println("test(Integer ) ");
System.out.println("test(String ) ");
d.m1(null);
Output:-
The method test(Integer) is ambiguous for the type Demo
Reason:
The main reason for getting the compile time error in the above example is that
here we have Integer and String as arguments which are not primitive data types in
java and this type of argument do not accept any null value. When the null value is
passed the compiler gets confused which method is to be selected as both the
methods in the above example are accepting null.
However, we can solve this to pass specific reference type rather than value.
Example:
In this example, we are passing specific type argument rather than null value.
Integer a = null;
obj.test(a);
String b = null;
obj.test(b);
Ex;-2
class Test
{
public void methodOne(String s)
{
System.out.println("String version");
}
public void methodOne(StringBuffer s)
{
System.out.println("StringBuffer version");
}
public static void main(String[] args)
{
Test t=new Test();
t.methodOne("arun");//String version
t.methodOne(new StringBuffer("sai"));//StringBuffer version
t.methodOne(null);//CE : reference to m1() is ambiquous
}
}
Var- arg methods (variable no of argument methods) (1.5)
Until 1.4v we can't declared a method with variable no. Of arguments.
If there is a change in no of arguments compulsory we have to define a new
method.
This approach increases length of the code and reduces readability.
But from 1.5 version onwards we can declare a method with variable no. Of
arguments such type of methods are called var-arg methods.
Advantage of Varargs:
Syntax of varargs:.
We can call or invoke this method by passing any no. Of int values including zero
number also.
Example:
class Test{
System.out.println("var-arg method");
m1();
m1(10);
m1(10,20,30);
Output:
var-arg method
var-arg method
var-arg method
Ex:-
Class VarargsExample2{
for(String s:values){
System.out.println(s);
}
display();//zero argument
display("hello");//one argument
display("my","name","is","varargs");//four arguments
Example:
class Test{
int total=0;
for(int i=0;i<x.length;i++){
total=total+x[i];
sum();
sum(10);
sum(10,20);
sum(10,20,30,40);
Output:
The sum: 0
The sum: 10
The sum: 30
Example:
class Test{
public static void sum(int... x){
int total=0;
for(int x1 : x){
total=total+x1;
}
System.out.println("The sum :"+total);
}
public static void main(String[] args){
sum();
sum(10);
sum(10,20);
sum(10,20,30,40);
}
}
Output:
The sum: 0
The sum: 10
The sum: 30
The sum: 100
Rules for varargs:
While using the varargs, you must follow some rules otherwise program code won't
compile. The rules are as follows:
Ex:-
class Parent {
public void property(){
System.out.println("cash+land+gold");
}
public void marry() {
System.out.println("Laxmi"); //overridden method
}
}
class Child extends Parent{ //overriding
public void marry() {
System.out.println("Kruthi/keerthi/Kajal/Pooja"); //overriding method
}
}
class Test {
public static void main(String[] args) {
Parent p=new Parent();
p.marry();//laxmi(parent method)
Child c=new Child();
c.marry();//Kruthi/keerthi/Kajal/Pooja (child method)
Parent p1=new Child();
p1.marry();//Kruthi/keerthi/Kajal/Pooja (child method)
}
}
Note: In overriding method resolution is always takes care by JVM based on
runtime object hence overriding is also considered as runtime polymorphism or
dynamic polymorphism or late binding.
Note: In overriding runtime object will play the role and reference type is dummy.
1. The method must have the same name as in the parent class
2. The method must have the same parameter as in the parent class.
3. There must be an IS-A relationship (inheritance).
Ex:- Understanding the problem without method overriding
class Vehicle{
void run(){
System.out.println("Vehicle is running");
}
}
//Creating a child class
class Bike extends Vehicle{
public static void main(String args[]){
//creating an instance of child class
Bike obj = new Bike();
//calling the method with child class instance
obj.run();
}
}
Output:
Vehicle is running
Problem is that I have to provide a specific implementation of run() method
in subclass that is why we use method overriding.
Example of with method overriding:-
We have defined the run method in the subclass as defined in the parent class but it
has some specific implementation. The name and parameter of the method are the
same, and there is IS-A relationship between the classes, so there is method
overriding.
Ex:-
class Vehicle{
//defining a method
void run(){
System.out.println("Vehicle is running");
}
}
//Creating a child class
class Bike2 extends Vehicle{
//defining the same method as in the parent class
void run(){
System.out.println("Bike is running safely");
}
public static void main(String args[]){
Bike2 obj = new Bike2();//creating object
obj.run();//calling method
}
}
Output:
Bike is running safely
Ex:-
class Bank{
int getRateOfInterest(){
return 0;
}
}
//Creating child classes.
class SBI extends Bank{
int getRateOfInterest(){
return 8;
}
}
Note: In overriding method names and arguments must be same. That is method
signature must be same.
4. Until 1.4 version the return types must be same but from 1.5 version onwards
covariant return types are allowed.
Note: Co-variant return type concept is applicable only for object types but not for
primitives.
5. According to this Child class method return type need not be same as Parent
class method return type its Child types also allowed.
6. Access modifier of child method must not restrictive than parent class method.
class Parent {
Output:
Ex:-
class Parent {
// private methods are not overridden
private void m1()
{
System.out.println("From parent m1()");
}
protected void m2()
{
System.out.println("From parent m2()");
}
}
// Driver class
class Main {
public static void main(String[] args)
{
Parent obj1 = new Parent();
obj1.m2();
Parent obj2 = new Child();
obj2.m2();
}
}
Output:
From parent m2()
From child m2()
7. Private, final and static methods cannot be overridden.
Note: Private methods are not visible in the Child classes hence overriding concept
is not applicable for private methods. Based on own requirement we can declare
the same Parent class private method in child class also. It is valid but not
overriding.
Ex: -
class Parent{
Private void m1(){
}
}
Class Child extends Parent{
Private void m1(){
}
}
Note: Parent class final methods we can't override in the Child class.
Note: Parent class non final methods we can override as final in child class. We
can override native methods in the child classes.
Example:
class Parent {
public final void m1() {
}
}
class Child extends Parent{
public void m1(){
}
}
}
Output:
Compile time error:
m1() in Child cannot override m1() in Parent; overridden method is final
Note: We should override Parent class abstract methods in Child classes to provide
implementation.
Example:
Ex:-
class Parent {
Case 1:
Example:
class Parent{
Output:
Case 2:
Case 3:
class Parent{
public static void methodOne() {}
class Parent {
// Static method in base class
// which will be hidden in subclass
static void m1()
{
System.out.println("From parent + "static m1()");
}
// Non-static method which will
// be overridden in derived class
void m2()
{
System.out.println("From parent "+ "non-static(instance) m2()");
}
}
class Child extends Parent {
// This method hides m1() in Parent
static void m1()
{
System.out.println("From child static m1()");
}
// Driver class
class Main {
public static void main(String[] args)
{
Parent obj1 = new Child();
METHOD HIDING:
All rules of method hiding are exactly same as overriding except the following
differences.
Overriding:-
Method hiding:-
Example:
class Parent {
System.out.println("parent class");
System.out.println("child class");
class Test{
p.m1();//parent class
c.m1();//child class
Note: If both Parent and Child class methods are non static then it will become
overriding and method resolution is based on runtime object. In this case the output
is
Parent class
Child class
Child class
A var-arg method should be overridden with var-arg method only. If we are trying
to override with normal method then it will become overloading but not overriding.
Example:
class Parent {
System.out.println("parent class");
System.out.println("child class");
}
class Test {
p.methodOne(10);//parent class
c.methodOne(10);//child class
p1.methodOne(10);//parent class
In the above program if we replace child class method with var arg then it will
become overriding. In this case the output is
Parent class
Child class
Child class
class Parent
int x=888;
int x=999;
class Test
System.out.println(p.x);//888
System.out.println(c.x);//999
System.out.println(p1.x);//888
}
}
Note: In the above program Parent and Child class variables, whether both are
static or non static whether one is static and the other one is non static there is no
change in the answer.
We can not override constructor as parent and child class can never have
constructor with same name(Constructor name must always be same as Class
name).
class OverloadingExample{
return a+b;
return a+b+c;
class Animal{
void eat(){
System.out.println("eating bread...");
}
void eat(){
System.out.println("eating meat...");