You've seen polymorphism through inheritance. Interfaces give you the same power without requiring a shared parent class. If Circle, Rectangle, and Triangle all implement Drawable, you can store them in a single Drawable[] array.
Drawable[] shapes = {
new Circle(5),
new Rectangle(3, 4),
new Triangle(6, 8)
};
for (Drawable d : shapes) {
d.draw();
}
At runtime, Java calls the correct draw() implementation for each object. The variable type is Drawable, but the actual method that runs depends on the object's real class. This is the same dynamic dispatch you saw with inheritance, but now it works across unrelated classes.