Polymorphism in Java

Polymorphism in OOPs

Polymorphism is one of the major principle of Object Oriented Programming Language.

Polymorphism is used perform single task in different way or different style.

Polymorphism is a derived from two Greek words : Poly and Morphs where Poly means Many and Morphs means Form.

For Example :

A Dog is a form of Animal and a Lion is a Form of Animal etc.

Polymorphism can be achieve by two way :

  • Overloading
  • Overriding

1. Overloading


  • Overloading is possible at least one class.
  •     class A{
    
        }
    

  • Same name of a method or constrcutor with different parameter is called Overloading.
  •     class A{
        
            //constructor overloading
            A(){}
            A(int i){}
    
            //method overloading
            void add(int i,int j){}
            void add(float i,float j){}
    
            //method overloading
            static void multiply(int i,int j){}
            static void multiply(float i,float j){}
        }
    

  • Overloading is also called static binding , early binding or compile time polymorphism.
  •     class A{
        
            static void add(int i,int j){
                System.out.println(i+j);
            }
    
            public static void main(String [] args){
    
                /*if we call add method and pass int type of argument 
                so there is no problem at compile time*/
                
                add(1,1);// result is 2
    
                /*but if we pass float type of argument in add method 
                then there is compile time error because compiler check
                this method add type of float parameter is 
                available or not in this class.*/ 
                
                add(1.2f,1.2f);// compile time error
    
                /*It means here compile take the decision 
                thats why it is call compile time polymorohism
                or static binding or early binding.*/
            }
        }
    

  • Yes we can change the return type of overloading methods.
  •     class A{
            static int add(int i,int j){
                return i+j;
            }
            
            static float add(float i,float j){
                return i+j;
            }
    
            public static void main(String [] args){
                /*if argument is non fractional number 
                then in java it assume as an int by default.*/    
                
                int out1=add(1,1);
                System.out.println(out1); //output is 2
            
                /*if argument is fractional number 
                then in java it assume as a double by default so we need
                to write f with argument to convert it into float type.*/
    
                int out2=add(1.2f,1.2f);
                System.out.println(out2); // output is 2.4
            }
        } 
    
        /*Note compiler always take the decision based on type that means if
        argument type is int then it call int parameterized method or if 
        argument is float then it call float type of parameterized method.*/
        

  • Yes main method also can be overloaded.
  •     class A{
    
            public static void main(String [] args){
                System.out.println("main method call by JVM by default");
            }
    
            public static void main(String args){
                System.out.println("main method call by explicit");
            }
        }
    
        Output is : main method call by JVM by default
        

  • Yes we can change the access modifiers of overloaded method.
  •     class A{
        
            private void show(int i){
                System.out.println("int " + i);
            }
    
            public void show(float i){
                System.out.println("float " + i);
            }
    
            public static void main(String [] args){
                A a=new A();
                a.show(1);
            }
        
        }
        
        Output is : int 1
        

  • Yes constructor can be overloaded.
  •     class A{
            A(){
                System.out.println("Hello");
            }        
    
            A(int i){
                System.out.println("Hi");
            }        
    
            public static void main(String [] args){
                new A();
    
                new A(10);
            }
        }  
        
        Output is : Hello
        Output is : Hi
        

  • Yes final method can be overloaded.
  •     class A{
            final void show(){
                System.out.println("Hello");
            }        
        
            final void show(int i){
                System.out.println("Hi");
            }        
        
            public static void main(String [] args){
                A a=new A();
                a.show();
                a.show(1);
            }
        }  
            
        Output is : Hello
        Output is : Hi
        

  • Yes a method or constructor also can be overloaded when parameter type are same but lenght of the parameter is different.
  •     class A{
            void show(int i){
                System.out.println("Hello");
            }        
            
            void show(int i,int j){
                System.out.println("Hi");
            }        
            
            public static void main(String [] args){
                A a=new A();
                a.show(1);
                a.show(1,1);
            }
        }  
                
        Output is : Hello
        Output is : Hi
        

    2. Overriding


  • Overriding is possible at least two class and there must be a relationship parent and child.
  •      class A{
    
         }   
    
         class B extends A{
    
         }
        

  • Same signature of a method is called Overriding.
  •     class Pen{
    
            void write(){
    
            }
    
        }   
        
        class BallPen extends Pen{
            
            void write(){
                System.out.println("Write to copy");
            }
        }
        

  • Only non static method can be Overriden by its child class.
  •     class Pen{
            
            //non static method
            void write(){
    
            }
    
        }   
        
        class BallPen extends Pen{
            
            //non static method        
            void write(){
                System.out.println("Write to copy");
            }
        }
        

  • To prevent a non static method to be Overriden we make it final.
  •     class Pen{
    
            final void write(){
    
            }
    
        }   
        
        class BallPen extends Pen{
            
            //child never override a final method.
    
        }
        

  • Main method can never be Overriden because main method is static and static method can never be inherited.
  •     class Pen{
            public static void main(String [] args){
                System.out.println("Parent main method");
            }
    
        }   
        
        class BallPen extends Pen{
    
            //this method can never overriden
            public static void main(String [] args){
                System.out.println("Child main method");
            }
        }
    
        class Test{
            
            public static void main(String [] args){
                BallPen.main(args);
                Pen.main(args);
            }
        }
    
        Output is : Child main method
        Output is : Parent main method
    
        

  • Yes we can chage access modifiers of overriden method in decreasing order.
  •         class A{
    
                void show(){
                    System.out.println("Hello show");
                }
    
            }
    
            class Test extends A{
    
                public void show(){
                    System.out.println("Hi show");
                }
    
            }
        

  • Yes we can chage return type of overriden method using co-varient return type.
  •     class A{
            Number add(int i,int j){
                return i+j;
            }
        }    
    
        class B extends A{
    
            //you can have same return type
            Number add(int i,int j){
                return i+j;
            }
    
            //or
    
            //you can have sub class but not super class of Number class.
            Integer add(int i,int j){
                return i+j;
            }
    
        }
    
        /* Note : Co-varient return type means there must 
           be a relationship between return types like :
           Integer , Float, Double, Long etc. parent class is Number class.
        

  • Constructor can never be Overriden because constructor can never be inherited.
  •     class Pen{
        
            Pen(){
                System.out.println("Parent constructor");
            }
    
        }   
        
        class BallPen extends Pen{
    
            BallPen(){
                
                System.out.println("Child constructor");
                
            }
    
        }
    
        class Test{
            
            public static void main(String [] args){
                new BallPen();
            }
        }
    
        Output is : Parent constructor
        Output is : Child constructor
    
        

  • Using static method child can achieve method hiding.
  •     class Pen{
            public static void main(String [] args){
                System.out.println("Parent main method");
            }
    
        }   
        
        class BallPen extends Pen{
    
            //this method hide the parent class main method
            public static void main(String [] args){
                System.out.println("Child main method");
            }
        }
    
        class Test{
            
            public static void main(String [] args){
    
                /*if you call static main method from child class 
                then you can call child class main but if child 
                class main method is not available then 
                child access the parent main method.*/
    
                BallPen.main(args);
            }
        }
    
        Output is : Child main method
    
        

  • To prevent a method hiding we make it final.
  •     class Pen{
            public final static void show(){
                System.out.println("Parent show method");
            }
    
        }   
        
        class BallPen extends Pen{
    
            //chils can never achieve method hiding
    
        }
    
        class Test{
            
            public static void main(String [] args){
    
                BallPen.main(args);
    
            }
        }
    
        Output is : Parent show method
    
        

  • Overriding is also called Runtime Polymorphism, Dynamic Binding or Late Binding because in this case decision take at runtime.
  •         class Mobile {
                public void call() {
                    System.out.println("mobile call");
                }
            }
            
        class Oppo extends Mobile {
        
            public void call() {
                System.out.println("oppo mobile call");
            }
    
        }
            
        class Samsung extends Mobile {
            
            public void call() {
                System.out.println("samsung mobile call");
            }
    
        }
            
        class User {
            
            Mobile mobile;
            
            public void setMobile(Mobile mob) {
                mobile = mob;
            }
            
            public Mobile getMobile() {
                return mobile;
            }
        }
            
        public class Test {
            public static void main(String[] args) {
            
                /*if user create object of
                 oppo then user can call via oppo but
                 if user create object of samsung then
                 user can call via samsung*/
                    
                User user = new User();
                
                user.setMobile(new Oppo());
                user.getMobile().call();
            
                user.setMobile(new Samsung());
                user.getMobile().call();
                    
                /*In this case decision takes at runtime, 
                  it means it depends on user which type 
                  of mobile object they are created.*/
            
            }
        }       
    
        Output is : oppo mobile call
        Output is : samsung mobile call
    
        

    No comments: