Let’s tie everything together with a fully runnable project showing how polymorphism (i.e., "many forms") simplifies code when multiple classes share the same interface.
Subsection7.6.1Interfaces and Polymorphism in Action
Incremental Building (Recommended Approach): Beginners often get overwhelmed if they see multiple files at once. A better strategy is building up step by step:
Add one class at a time: For instance, write MusicTrack.java implementing Playable, then compile it. If you see a compiler error, fix it before moving on.
Add more classes incrementally: (e.g., PodcastEpisode, Audiobook) repeating the compile/test cycle each time. This prevents a flood of errors all at once.
Finally, unify them in a more comprehensive MediaPlayer class: with a full main method demonstrating all classes. If something breaks, you know which recent addition is likely responsible.
Compile (step by step or all at once): In your project folder, run javac *.java to compile all .java files. If you prefer incremental compilation, do javac Playable.java first, then each new class as you create it.
public class Livestream implements Playable {
@Override
public void play() {
System.out.println("Streaming live...");
}
}
// Then in main (or anywhere):
playMedia(new Livestream()); // prints "Streaming live..."
This is polymorphism. The same "playMedia" method call does different things depending on the object’s class.
A method drawShape(Drawable shape) is created in a separate class. This method takes a Drawable object as a parameter and calls its draw() method, demonstrating polymorphism.
The Drawable interface must provide an implementation for the draw() method.
No. Interfaces in Java only define method signatures without providing implementations (except for default and static methods, which are not used here). The actual implementation of draw() must be provided by classes that implement the interface.
The Circle and Rectangle classes must override the draw() method from the Drawable interface.
Correct! The Circle and Rectangle classes must override the draw() method from the Drawable interface.
The drawShape(Drawable shape) method must be defined inside the Drawable interface.
No! Interfaces are meant to define behavior but not necessarily contain utility methods like drawShape(). This method is better suited for a separate class where it can accept any Drawable object and invoke its draw() method.
We cannot pass a Circle or Rectangle object to drawShape() because they are not of type Drawable.
Since Circle and Rectangle implement Drawable, they are considered polymorphic types of Drawable. This allows them to be passed as arguments to drawShape(Drawable shape), which expects a Drawable parameter.