Polymorphism in Java is a concept that allows objects of different classes to be treated as if they were of the same type. It allows you to write code that can work with objects of multiple classes, without knowing the specific type of each object at compile time.

Polymorphism is implemented in Java through inheritance and interfaces. Inheritance is the process by which one class inherits the properties and methods of another class, and interfaces define a set of methods that a class must implement. By using these features, you can create classes that share common properties and behaviors, and then use those classes interchangeably.

Here's an example of polymorphism in Java using inheritance:

public class Animal {
    public void makeSound() {
        System.out.println("The animal makes a sound");
    }
}

public class Dog extends Animal {
    public void makeSound() {
        System.out.println("The dog barks");
    }
}

public class Cat extends Animal {
    public void makeSound() {
        System.out.println("The cat meows");
    }
}

public class PolymorphismExample {
    public static void main(String[] args) {
        Animal animal1 = new Dog();
        Animal animal2 = new Cat();
        
        animal1.makeSound(); // prints "The dog barks"
        animal2.makeSound(); // prints "The cat meows"
    }
}

In this example, we have an Animal class with a makeSound() method, and two subclasses Dog and Cat that override the makeSound() method. In the main() method, we create instances of the Dog and Cat classes, but we declare them as Animal objects. When we call the makeSound() method on these objects, the version of the method that is called depends on the actual type of the object at runtime. This is an example of dynamic binding, which is a key feature of polymorphism.

Polymorphism can also be implemented using interfaces. Here's an example:

public interface Shape {
    public void draw();
}

public class Circle implements Shape {
    public void draw() {
        System.out.println("Drawing a circle");
    }
}

public class Square implements Shape {
    public void draw() {
        System.out.println("Drawing a square");
    }
}

public class PolymorphismExample {
    public static void main(String[] args) {
        Shape shape1 = new Circle();
        Shape shape2 = new Square();
        
        shape1.draw(); // prints "Drawing a circle"
        shape2.draw(); // prints "Drawing a square"
    }
}

In this example, we have a Shape interface with a draw() method, and two classes Circle and Square that implement the Shape interface. In the main() method, we create instances of the Circle and Square classes, but we declare them as Shape objects. When we call the draw() method on these objects, the version of the method that is called depends on the actual type of the object at runtime. This is another example of dynamic binding and polymorphism.

Here's another example:

public interface Movable {
    void move();
}

public class Car implements Movable {
    @Override
    public void move() {
        System.out.println("Car moves on four wheels.");
    }
}

public class Bicycle implements Movable {
    @Override
    public void move() {
        System.out.println("Bicycle moves on two wheels.");
    }
}

public class PolymorphismExample {
    public static void main(String[] args) {
        Movable[] movables = new Movable[2];
        movables[0] = new Car();
        movables[1] = new Bicycle();

        for (Movable movable : movables) {
            movable.move();
        }
    }
}

In this example, we have an interface Movable with a method move(), and two classes Car and Bicycle that implement the Movable interface. We create an array of Movable objects that can hold objects of type Car or Bicycle. Then, we create instances of Car and Bicycle and store them in the array.

In the main() method, we loop through the array of Movable objects and call the move() method on each object. Because both Car and Bicycle classes implement the Movable interface, we can call the move() method on both objects, even though they are of different types. This is an example of polymorphism using interfaces.