Teachnique
      CourseRoadmaps
      Login

      OverviewHistoryFeaturesJava 8 - New Featuresvs C++Virtual Machine(JVM)JDK vs JRE vs JVMHello World ProgramEnvironment SetupBasic SyntaxVariable TypesData TypesType CastingUnicode SystemBasic OperatorsCommentsStreamsNew Date-Time API

      Loop ControlDecision Makingif-else Statementswitch statementfor loopfor each Loopwhile Loopdo...while Loopbreak Statementcontinue Statement

      OOPs (Object-Oriented Programming) ConceptsObject and ClassesClass AttributesClass MethodsMethodsVariable ScopesConstructorsAccess ModifiersInheritanceAggregationPolymorphismOverridingMethod OverloadingDynamic BindingStatic BindingInstance Initializer BlockAbstractionEncapsulationInterfacesPackagesInner classesStatic ClassesAnonymous ClassesSingleton ClassWrapper ClassesEnum Class

      Number ClassBoolean classCharacter ClassArraysMath Class

      File ClassCreating FilesWrite To FilesReading FileDelete FilesDirectory OperationsFiles and I/O

      ExceptionsTry Catch BlockTry with ResourcesMultiple Catch BlocksNested Try BlockFinally BlockThrows and Throw | Throw an ExceptionException PropagationBuilt-in ExceptionsCustom Exception

      MultithreadingThread Life CycleCreating a ThreadStarting a ThreadJoining ThreadsNaming a Thread with ExamplesScheduling Threads with ExamplesThread PoolsMain ThreadThread PriorityDaemon ThreadThreadGroup ClassJVM Shutdown Hook

      Thread SynchronizationBlock SynchronizationStatic SynchronizationInter Thread CommunicationThread DeadlockInterrupting ThreadThread ControlReentrant Monitor

      NetworkingSocket ProgrammingURL ProcessingURL ClassURLConnection ClassHttpURLConnection ClassSocket Class with ExamplesGenerics

      Collections FrameworkCollection Interface

      List InterfaceArrayList Class

      Queue InterfaceArrayDeque Class

      Map InterfaceSortedMap Interface

      Set InterfaceSortedSet Interface

      Data Structures Enumeration Interface BitSet Class

      How to Use Iterator?How to Use Comparator?How to Use Comparable?

      RecursionRegular ExpressionsSerializationString ClassJava Arrays - Class

      Feedback

      Submit request if you have any questions.

      Course
      Polymorphism

      Java Tutorial

      This Java tutorial is tailored for newcomers, offering a journey from basic principles to complex Java programming techniques. Completing this tutorial equips you with a solid understanding of Java, preparing you for advanced learning. You'll emerge ready to tackle the challenges of becoming a top-tier software engineer, with the skills to innovate and excel in the vast world of software development.

      Polymorphism

      Polymorphism in Java

      Polymorphism is the ability of an object to take on many forms. Polymorphism is an important feature of Java OOPs concept and it allows us to perform multiple operations by using the single name of any method (interface). Any Java object that can pass more than one IS-A test is considered to be polymorphic. In Java, all Java objects are polymorphic since any object will pass the IS-A test for its own type and for the class Object.

      Use of Polymorphism in Java

      The most common use of polymorphism in OOP occurs when a parent class reference is used to refer to a child class object.
      It is important to know that the only possible way to access an object is through a reference variable. A reference variable can be of only one type. Once declared, the type of a reference variable cannot be changed.
      The reference variable can be reassigned to other objects provided that it is not declared final. The type of the reference variable would determine the methods that it can invoke on the object.
      A reference variable can refer to any object of its declared type or any subtype of its declared type. A reference variable can be declared as a class or interface type.

      Java Polymorphism Example

      Let us look at an example.
      public interface Vegetarian{}
      public class Animal{}
      public class Deer extends Animal implements Vegetarian{}
      Now, the Deer class is considered to be polymorphic since this has multiple inheritance. Following are true for the above examples −
      • A Deer IS-A Animal
      • A Deer IS-A Vegetarian
      • A Deer IS-A Deer
      • A Deer IS-A Object
      When we apply the reference variable facts to a Deer object reference, the following declarations are legal
      Deer d = new Deer();
      Animal a = d;
      Vegetarian v = d;
      Object o = d;
      All the reference variables d, a, v, o refer to the same Deer object in the heap.

      Java Polymorphism Implementation

      In this example, we're showcasing the above concept by creating the object of a Deer and assigning the same to the references of superclasses or implemented interface.
      interface Vegetarian{}
      class Animal{}
      public class Deer extends Animal implements Vegetarian{
      public static void main(String[] args) {
      Deer d = new Deer();
      Animal a = d;
      Vegetarian v = d;
      Object o = d;
      System.out.println(d instanceof Deer);
      System.out.println(a instanceof Deer);
      System.out.println(v instanceof Deer);
      System.out.println(o instanceof Deer);
      }
      }
      Output
      true
      true
      true
      true

      Types of Java Polymorphism

      There are two types of polymorphism in Java:
      1. Compile Time Polymorphism
      2. Run Time Polymorphism

      Compile Time Polymorphism in Java

      Compile-time polymorphism is also known as static polymorphism and it is implemented by method overloading.

      Example: Compile Time Polymorphism

      This example has multiple methods having the same name to achieve the concept of compile-time polymorphism in Java.
      // Java Example: Compile Time Polymorphism
      public class Main {
      // method to add two integers
      public int addition(int x, int y) {
      return x + y;
      }
      
      // method to add three integers
      public int addition(int x, int y, int z) {
      return x + y + z;
      }
      
      // method to add two doubles
      public double addition(double x, double y) {
      return x + y;
      }
      
      // Main method
      public static void main(String[] args) {
      // Creating an object of the Main method
      Main number = new Main();
      
      // calling the overloaded methods
      int res1 = number.addition(444, 555);
      System.out.println("Addition of two integers: " + res1);
      
      int res2 = number.addition(333, 444, 555);
      System.out.println("Addition of three integers: " + res2);
      
      double res3 = number.addition(10.15, 20.22);
      System.out.println("Addition of two doubles: " + res3);
      }
      }
      Output
      Addition of two integers: 999
      Addition of three integers: 1332
      Addition of two doubles: 30.369999999999997

      Run Time Polymorphism in Java

      Run time polymorphism is also known as dynamic method dispatch and it is implemented by the method overriding.

      Example: Run Time Polymorphism

      // Java Example: Run Time Polymorphism
      class Vehicle {
      public void displayInfo() {
      System.out.println("Some vehicles are there.");
      }
      }
      
      class Car extends Vehicle {
      // Method overriding
      @Override
      public void displayInfo() {
      System.out.println("I have a Car.");
      }
      }
      
      class Bike extends Vehicle {
      // Method overriding
      @Override
      public void displayInfo() {
      System.out.println("I have a Bike.");
      }
      }
      
      public class Main {
      public static void main(String[] args) {
      Vehicle v1 = new Car(); // Upcasting
      Vehicle v2 = new Bike(); // Upcasting
      
      // Calling the overridden displayInfo() method of Car class
      v1.displayInfo();
      
      // Calling the overridden displayInfo() method of Bike class
      v2.displayInfo();
      }
      }
      Output
      I have a Car.
      I have a Bike.

      Virtual Method and Run Time Polymorphism in Java

      In this section, I will show you how the behavior of overridden methods in Java allows you to take advantage of polymorphism when designing your classes.
      We already have discussed method overriding, where a child class can override a method in its parent. An overridden method is essentially hidden in the parent class, and is not invoked unless the child class uses the super keyword within the overriding method.

      Example: Implementation of Run Time Polymorphism with Virtual Methods

      /* File name : Employee.java */
      public class Employee {
      private String name;
      private String address;
      private int number;
      
      public Employee(String name, String address, int number) {
      System.out.println("Constructing an Employee");
      this.name = name;
      this.address = address;
      this.number = number;
      }
      
      public void mailCheck() {
      System.out.println("Mailing a check to " + this.name + " " + this.address);
      }
      
      public String toString() {
      return name + " " + address + " " + number;
      }
      
      public String getName() {
      return name;
      }
      
      public String getAddress() {
      return address;
      }
      
      public void setAddress(String newAddress) {
      address = newAddress;
      }
      
      public int getNumber() {
      return number;
      }
      }
      Now suppose we extend Employee class as follows
      /* File name : Salary.java */
      public class Salary extends Employee {
      private double salary; // Annual salary
      public Salary(String name, String address, int number, double salary) {
      super(name, address, number);
      setSalary(salary);
      }
      public void mailCheck() {
      System.out.println("Within mailCheck of Salary class ");
      System.out.println("Mailing check to " + getName()
      + " with salary " + salary);
      }
      public double getSalary() {
      return salary;
      }
      public void setSalary(double newSalary) {
      if(newSalary >= 0.0) {
      salary = newSalary;
      }
      }
      public double computePay() {
      System.out.println("Computing salary pay for " + getName());
      return salary/52;
      }
      }
      Now, you study the following program carefully and try to determine its output
      /* File name : VirtualDemo.java */
      public class VirtualDemo {
      
      public static void main(String [] args) {
      Salary s = new Salary("Mohd Mohtashim", "Ambehta, UP", 3, 3600.00);
      Employee e = new Salary("John Adams", "Boston, MA", 2, 2400.00);
      System.out.println("Call mailCheck using Salary reference --");
      s.mailCheck();
      System.out.println("\n Call mailCheck using Employee reference--");
      e.mailCheck();
      }
      }
      
      class Employee {
      private String name;
      private String address;
      private int number;
      
      public Employee(String name, String address, int number) {
      System.out.println("Constructing an Employee");
      this.name = name;
      this.address = address;
      this.number = number;
      }
      
      public void mailCheck() {
      System.out.println("Mailing a check to " + this.name + " " + this.address);
      }
      
      public String toString() {
      return name + " " + address + " " + number;
      }
      
      public String getName() {
      return name;
      }
      
      public String getAddress() {
      return address;
      }
      
      public void setAddress(String newAddress) {
      address = newAddress;
      }
      
      public int getNumber() {
      return number;
      }
      }
      
      class Salary extends Employee {
      private double salary; // Annual salary
      public Salary(String name, String address, int number, double salary) {
      super(name, address, number);
      setSalary(salary);
      }
      public void mailCheck() {
      System.out.println("Within mailCheck of Salary class ");
      System.out.println("Mailing check to " + getName()
      + " with salary " + salary);
      }
      public double getSalary() {
      return salary;
      }
      public void setSalary(double newSalary) {
      if(newSalary >= 0.0) {
      salary = newSalary;
      }
      }
      public double computePay() {
      System.out.println("Computing salary pay for " + getName());
      return salary/52;
      }
      }
      Output
      Constructing an Employee
      Constructing an Employee
      
      Call mailCheck using Salary reference --
      Within mailCheck of Salary class
      Mailing check to Mohd Mohtashim with salary 3600.0
      
      Call mailCheck using Employee reference--
      Within mailCheck of Salary class
      Mailing check to John Adams with salary 2400.0
      Here, we instantiate two Salary objects. One using a Salary reference s, and the other using an Employee reference e.
      While invoking s.mailCheck(), the compiler sees mailCheck() in the Salary class at compile time, and the JVM invokes mailCheck() in the Salary class at run time.
      mailCheck() on e is quite different because e is an Employee reference. When the compiler sees e.mailCheck(), the compiler sees the mailCheck() method in the Employee class.
      Here, at compile time, the compiler used mailCheck() in Employee to validate this statement. At run time, however, the JVM invokes mailCheck() in the Salary class.
      This behavior is referred to as virtual method invocation, and these methods are referred to as virtual methods. An overridden method is invoked at run time, no matter what data type the reference is that was used in the source code at compile time.
      Print Page