Posted in

POLYMORPHISM PROGRAMS AND ALGORITHMS IN JAVA

1. Write a Java program that demonstrates method overloading. Create a class Calculator with overloaded methods to add both integers and floating-point numbers?

Algorithm :

  • Start
  • Define a class named Calculator
    • Implement three overloaded methods named add():
      • One for int, int
      • One for float, float
      • One for int, float
  • Define another class named Main with the main() method
  • Inside main(), create an object calc of class Calculator
  • Call calc.add(5, 10) and print the result
  • Call calc.add(5.5f, 10.5f) and print the result
  • Call calc.add(5, 10.5f) and print the result
  • End

Program :

class Calculator {
    public int add(int a, int b) {
        return a + b;
    }
    public float add(float a, float b) {
        return a + b;
    }
    public float add(int a, float b) {
        return a + b;
    }
}
public class Main {
    public static void main(String[] args) {
        Calculator calc = new Calculator();
        System.out.println(“Sum of 5 and 10 (int): ” + calc.add(5, 10));        
        System.out.println(“Sum of 5.5 and 10.5 (float): ” + calc.add(5.5f, 10.5f)); 
        System.out.println(“Sum of 5 and 10.5 (int + float): ” + calc.add(5, 10.5f)); 
    }
}

Output :   

 Sum of 5 and 10 (int): 15
 Sum of 5.5 and 10.5 (float): 16.0
 Sum of 5 and 10.5 (int + float): 15.5

Explanation :

             This Java program demonstrates method overloading using a Calculator class that has three add() methods with different parameter types: one for two integers, one for two floats, and one for an integer and a float. In the main method of the Main class, a Calculator object is created, and the appropriate add() method is called based on the argument types. When calc.add(5, 10) is called, it matches the add(int, int) method and returns 15. When calc.add(5.5f, 10.5f) is called, it matches the add(float, float) method and returns 16.0. Finally, calc.add(5, 10.5f) matches add(int, float) due to Java’s type promotion rules and returns 15.5. This shows how Java selects the correct overloaded method at compile time based on parameter types.

2. Write a program to create a superclass Animal with a method makeSound(). Derive two classes Dog and Cat from Animal and override the makeSound() method. Demonstrate polymorphism by calling the makeSound() method on a reference of type Animal?

Algorithm :

  • Start the program.
  • Define a base class Animal with a method makeSound().
  • Define a subclass Dog that overrides makeSound() to print “Dog barks”.
  • Define another subclass Cat that overrides makeSound() to print “Cat meows”.
  • In the Main class, create objects:
    • myAnimal as an Animal
    • myDog as a Dog (referenced by Animal)
    • myCat as a Cat (referenced by Animal)
  • Call makeSound() on all three objects.
  • End the program.

Program :

    class Animal {
        public void makeSound() {
        System.out.println(“Animal makes a sound”);
        }
    }
     class Dog extends Animal {
    public void makeSound() {
        System.out.println(“Dog barks”);
    }
}
    class Cat extends Animal {
    public void makeSound() {
        System.out.println(“Cat meows”);
    }
}
public class Main {
    public static void main(String[] args) {
        Animal myAnimal = new Animal();
        Animal myDog = new Dog();       
        Animal myCat = new Cat();       
        myAnimal.makeSound(); 
        myDog.makeSound();    
        myCat.makeSound(); 
    }
}

Output :    

Animal makes a sound
Dog barks
Cat meows

Explanation :

                This Java program demonstrates runtime polymorphism through method overriding. The base class Animal defines a method makeSound(), which is overridden in its subclasses Dog and Cat. In the main method, objects are created using Animal references but instantiated with Dog and Cat objects. When makeSound() is called on each, Java dynamically determines which version to execute based on the actual object type. As a result, myAnimal.makeSound() prints “Animal makes a sound”, myDog.makeSound() prints “Dog barks”, and myCat.makeSound() prints “Cat meows”.

3. Write a program to define an interface Shape with a method draw(). Implement the Shape interface in two classes, Circle and Rectangle, and demonstrate polymorphism by calling the draw() method using a Shape reference?

Algorithm :

  • Start the program.
  • Define an interface Shape with an abstract method draw().
  • Create a class Circle that implements Shape and defines draw() to print “Drawing a Circle”.
  • Create a class Rectangle that implements Shape and defines draw() to print “Drawing a Rectangle”.
  • In the Main class, create two Shape references:
    • myShape1 assigned to a new Circle object.
    • myShape2 assigned to a new Rectangle object.
  • Call the draw() method on both myShape1 and myShape2.
  • End the program.

Program :

interface Shape {
    void draw();
     }
   class Circle implements Shape {
     public void draw() {
        System.out.println(“Drawing a Circle”);
    }
}
class Rectangle implements Shape {
    public void draw() {
        System.out.println(“Drawing a Rectangle”);
    }
}
public class Main {
    public static void main(String[] args) {
        Shape myShape1 = new Circle();  
        Shape myShape2 = new Rectangle();
        myShape1.draw(); 
        myShape2.draw(); 
    }
}

Output :   

Drawing a Circle
Drawing a Rectangle

Explanation :

                This program demonstrates the concept of interfaces and polymorphism in Java. The Shape interface defines a method draw(), which is implemented by both Circle and Rectangle classes. In the main method, Shape interface references are used to point to objects of Circle and Rectangle. When the draw() method is called on these references, the corresponding implementation in each class is executed, printing “Drawing a Circle” and “Drawing a Rectangle”.

4. Write a program to create a superclass Shape with a method area(). Derive two classes Circle and Rectangle from Shape and override the area() method to calculate the respective areas. Demonstrate polymorphism by calling the area() method on a Shape reference?

Algorithm :

  • Start the program.
  • Define a base class Shape with a method area() that returns 0.
  • Create a subclass Circle:
    • Add a radius attribute.
    • Define a constructor to initialize radius.
    • Override area() to return π × radius².
  • Create a subclass Rectangle:
    • Add length and width attributes.
    • Define a constructor to initialize both.
    • Override area() to return length × width.
  •  In the Main class:
    • Create a Shape reference myCircle and assign a Circle object with radius 5.
    • Create a Shape reference myRectangle and assign a Rectangle object with length 4 and width 6.
  • Call area() on both objects and print the results.
  • End the program.

Program :

     class Shape {
    public double area() {
        return 0;
    }
}
class Circle extends Shape {
    private double radius;
    public Circle(double radius) {
        this.radius = radius;
    }
    @Override
    public double area() {
        return Math.PI * radius * radius; // Area = π * r²
    }
}
class Rectangle extends Shape {
    private double length, width;
    // Constructor for Rectangle
    public Rectangle(double length, double width) {
        this.length = length;
        this.width = width;
    }
    public double area() {
        return length * width; // Area = length * width
    }
}
public class Main {
    public static void main(String[] args) {
        Shape myCircle = new Circle(5);   
        Shape myRectangle = new Rectangle(4, 6);
        System.out.println(“Area of Circle: ” + myCircle.area()); 
        System.out.println(“Area of Rectangle: ” + myRectangle.area());
    }
}

Output :   

 Area of Circle: 78.53981633974483
Area of Rectangle: 24.0

Explanation :

This program illustrates inheritance and method overriding in Java to calculate the area of different shapes. The base class Shape provides a generic area() method that returns 0. The Circle and Rectangle classes extend Shape and override the area() method to provide specific formulas: πr² for circles and length × width for rectangles. In the main method, Shape references are used to hold Circle and Rectangle objects. When area() is called, Java dynamically invokes the appropriate overridden method based on the actual object type, demonstrating runtime polymorphism.

5. Write a program to create an interface Animal with a method sound(). Implement this interface in classes Dog and Cat. Create a List<Animal>, add instances of Dog and Cat, and call the sound() method on each element in the list?

Algorithm :

  • Start the program.
  • Define an interface Animal with an abstract method sound().
  • Create a class Dog that implements Animal and overrides sound() to print “Dog barks”.
  • Create a class Cat that implements Animal and overrides sound() to print “Cat meows”.
  • In the Main class:
    • Create a List of Animal objects using ArrayList.
    • Add a Dog and a Cat object to the list.
  • Loop through each Animal in the list and call its sound() method.
  • End the program.

Program :

    import java.util.ArrayList;
     import java.util.List;
     interface Animal {
    void sound();
     }
class Dog implements Animal {
    @Override
    public void sound() {
        System.out.println(“Dog barks”);
    }
}
class Cat implements Animal {
    @Override
    public void sound() {
        System.out.println(“Cat meows”);
    }
}
public class Main {
    public static void main(String[] args) {
        List<Animal> animals = new ArrayList<>();
        animals.add(new Dog());
        animals.add(new Cat());
        for (Animal animal : animals) {
            animal.sound(); 
        }
    }
}

Output:   

Dog barks
Cat meows

Explanation :

              This program demonstrates the use of interfaces, polymorphism, and collections in Java. The Animal interface defines the sound() method, which is implemented differently by Dog and Cat classes. In the main method, an ArrayList of Animal type is created, and both a Dog and a Cat object are added to it. Using a for-each loop, the program calls sound() on each element. Java dynamically invokes the correct method implementation for each object, printing “Dog barks” and “Cat meows”.

6. Write a program to create a superclass Parent with a static method display(). Create a subclass Child that also defines a static method display()?

Algorithm :

  • Start the program.
  • Define a class Parent with a static method display() that prints a message.
  • Define a class Child that extends Parent and also defines a static display() method (hiding the one in Parent).
  • In the Main class:
    • Call Parent.display() → executes Parent’s static method.
    • Call Child.display() → executes Child’s static method.
    • Create a Parent reference pointing to a Child object, and call display() using this reference.
  • Observe the output.    
  • End the program.

Program :

       class Parent {
    public static void display() {
        System.out.println(“Display method in Parent class”);
    }
}
class Child extends Parent {
    public static void display() {
        System.out.println(“Display method in Child class”);
    }
}
public class Main {
    public static void main(String[] args) {
        Parent.display(); 
        Child.display();  
        Parent parent = new Child();
        parent.display(); 
    }
}

Output :    

 Display method in Parent class
 Display method in Child class
 Display method in Parent class

Explanation :

                This program demonstrates method hiding with static methods in Java. The Parent and Child classes both define a static method named display(). Unlike instance methods, static methods are not overridden but hidden, and they are resolved at compile-time based on the reference type. So, Parent.display() calls the method in Parent, and Child.display() calls the one in Child. When a Parent reference (Parent parent = new Child()) is used to call display(), it still executes Parent’s version, not Child’s.

7. Write a program to create a base class Parent with a static method showMessage(). Then, create a derived class Child that hides the showMessage() method. Demonstrate how static methods are not polymorphic by calling showMessage() on a reference of type Parent and Child?

Algorithm :

  • Start the program.
  • Define a class Parent with a static method showMessage() that prints a message.
  • Define a class Child that extends Parent and defines its own static method showMessage(), which hides the one in Parent.
  • In the Main class:
    • Create an object parent of type Parent and call showMessage().
    • Create an object child of type Child and call showMessage().
    • Create a Parent reference polyReference that refers to a Child object and call showMessage().
  • Observe the output.
  • End the program.

Program :

    class Parent {
    public static void showMessage() {
        System.out.println(“Message from Parent class”);
    }
}
class Child extends Parent {
    public static void showMessage() {
        System.out.println(“Message from Child class”);
    }
}
public class Main {
    public static void main(String[] args) {
        Parent parent = new Parent();
        parent.showMessage(); 
        Child child = new Child();
        child.showMessage();  
        Parent polyReference = new Child();
        polyReference.showMessage(); 
    }
}

Output :  

 Message from Parent class
 Message from Child class
Message from Parent class

Explanation :

This program illustrates static method hiding in Java. Both Parent and Child classes define a static method showMessage(). Since static methods are bound at compile-time, they are not polymorphic. When showMessage() is called using a Parent reference—even if it points to a Child object—it executes the Parent version. Thus, parent.showMessage() and polyReference.showMessage() both call the method in Parent, while child.showMessage() calls the method in Child. This behavior highlights that static methods depend on the reference type, not the actual object type.

8. Write a program to create an interface Playable with a method play(). Create multiple classes Guitar, Drums, and Piano that implement Playable. Demonstrate polymorphism by storing these objects in an array or list and invoking the play() method on each object?

Algorithm :

  • Start the program.
  • Define an interface Playable with an abstract method play().
  • Create three classes Guitar, Drums, and Piano that implement the Playable interface and override the play() method to print their respective messages.
  • In the Main class:
    • Create a list of Playable type using ArrayList.
    • Add objects of Guitar, Drums, and Piano to the list.
  • Use a for-each loop to iterate through the list and call the play() method on each instrument.
  • End the program.

Program :

  import java.util.ArrayList;
  import java.util.List;
  interface Playable {
    void play();
}
class Guitar implements Playable {
    @Override
    public void play() {
        System.out.println(“Playing the Guitar”);
    }
}
class Drums implements Playable {
    @Override
    public void play() {
        System.out.println(“Playing the Drums”);
    }
}
class Piano implements Playable {
    @Override
    public void play() {
        System.out.println(“Playing the Piano”);
    }
}
public class Main {
    public static void main(String[] args) {
        List<Playable> instruments = new ArrayList<>();
        instruments.add(new Guitar());
        instruments.add(new Drums());
        instruments.add(new Piano());
        for (Playable instrument : instruments) {
            instrument.play();
        }
    }
}

Output :   

 Playing the Guitar
 Playing the Drums
 Playing the Piano

Explanation :

              This program demonstrates interface implementation and polymorphism using a musical instrument example. The Playable interface defines a method play(), which is implemented uniquely in Guitar, Drums, and Piano classes. In the main method, a list of Playable objects is created and filled with instances of each instrument. The program then uses a loop to call the play() method on each object, resulting in output specific to the instrument type. This showcases how interfaces and polymorphism allow writing flexible and reusable code where different classes can be treated uniformly.

Leave a Reply

Your email address will not be published. Required fields are marked *