Java Polymorphism
Store different objects in a parent-typed variable so one call name can run different bodies. Keep horn on Machine printing tone. On Truck, rewrite horn to print honk. On Car, rewrite horn to print beep. In Yard.java, assign Machine m = new Machine();, Machine t = new Truck();, and Machine c = new Car();, then call horn on each. Compile with javac Yard.java and run java Yard. The screen should show tone, then honk, then beep. A second demo keeps only the two children as Machine references. Leave equals for the next page — this lesson is one parent type holding many forms.
One parent type, three horn bodies
The abstract page left a method unfinished for children to fill. This page focuses on the call through a parent-typed variable. Open Yard.java. Keep the public class name Yard. Delete leftover abstract-only demos if they bury the parent-typed story, leftover enum Level files, leftover path demos, and any keyboard Scanner. The program must not wait for typing. No import line is required.
Declare a normal parent with a horn body:
class Machine {
void horn() {
System.out.println("tone");
}
}
Declare children with extends Machine and their own horn bodies that print honk and beep. Matching name and empty parameter list mean each child overrides the parent method.
Inside Yard.main, build three variables whose declared type is Machine:
Machine m = new Machine();
Machine t = new Truck();
Machine c = new Car();
Then call:
m.horn();
t.horn();
c.horn();
The declared type is Machine for all three. The real object decides which horn body runs.
class Machine {
void horn() {
System.out.println("tone");
}
}
class Truck extends Machine {
void horn() {
System.out.println("honk");
}
}
class Car extends Machine {
void horn() {
System.out.println("beep");
}
}
public class Yard {
public static void main(String[] args) {
Machine m = new Machine();
Machine t = new Truck();
Machine c = new Car();
m.horn();
t.horn();
c.horn();
}
}
From the folder that holds Yard.java, run javac Yard.java. When parentheses, braces, and semicolons match, javac writes no line of its own. Then run java Yard — not java Yard.java. Leave the .java ending off the run command. Keep one public class in the file so the name matches Yard. Helper types stay without public on this beginner shape.
The screen shows tone, then honk, then beep. Walk the run once. Java starts at Yard.main. m holds a plain Machine, so m.horn() prints tone. t holds a Truck even though the variable type says Machine, so t.horn() prints honk. c holds a Car, so c.horn() prints beep. Same call spelling. Three bodies.
Point at each assignment while you read the screen line that matches it. The first line belongs to the plain machine. The second line belongs to the truck object behind a machine-typed name. The third line belongs to the car object behind a machine-typed name. That matching game is the whole lesson in one pass.
If you still see only honk then park from an abstract demo, switch to the polymorphism teaching file and run java Yard again. If every variable is typed Truck or Car only, you are not yet showing the parent-typed form this page teaches — keep the Machine type on the left of the assignments for the demo.
Say the rule out loud while you watch the screen: variable type can be the parent, object can be the child, call runs the child’s body when the child overrode the method. Do not invent an equals override on this page. That topic waits for the next lesson.
Two children through Machine references
A second program keeps the overrides. main builds only Truck and Car, still stored as Machine, and calls horn on each.
class Machine {
void horn() {
System.out.println("tone");
}
}
class Truck extends Machine {
void horn() {
System.out.println("honk");
}
}
class Car extends Machine {
void horn() {
System.out.println("beep");
}
}
public class Yard {
public static void main(String[] args) {
Machine t = new Truck();
Machine c = new Car();
t.horn();
c.horn();
}
}
Compile with javac Yard.java, then run java Yard. The screen shows honk, then beep. There is no plain Machine object in this second demo, yet both variables are still typed Machine. The child objects supply the bodies. That is the same polymorphism idea with a shorter screen.
Read the assignment lines once more: left side Machine, right side new Truck() or new Car(). The left side names the parent type you will call through. The right side names the real object. Keep extends Machine on both children so those assignments stay legal.
If leftover abstract demos still sit nearby, keep them as history. For this lesson run the polymorphism teaching file so the screen shows tone / honk / beep or honk / beep, not park as the main story. If javac complains about duplicate public classes, keep only Yard public.
Which horn body runs
📊 Who runs for each Machine variable
| Variable | Real object | horn prints |
|---|---|---|
m |
Machine |
tone |
t |
Truck |
honk |
c |
Car |
beep |
Compared with abstract fills
On the abstract page, Machine left horn unfinished and children filled it, often with a shared park. On this page, Machine already has a tone body, children override it, and parent-typed variables hold the objects. You still compile Yard.java and run java Yard. The new tokens are parent-typed assignments like Machine t = new Truck(); and the three different prints from one call name.
If a leftover abstract file is still open, you may see abstract void horn(); and park. Switch to the polymorphism file so Machine has a normal horn body and main assigns Machine variables to different objects. Keep equals demos off this page. Keep keyboard input off this page.
Before equals
You can assign Machine variables to Machine, Truck, and Car objects and see tone, then honk, then beep. You can keep only the two children as Machine references and see honk then beep. Compile Yard.java and run java Yard for each kept demo in turn. The call used the body’s owner. The next page is equals, where two objects are compared for sameness in a teaching-safe way.
Keep the three-object demo for a clear parent-plus-children screen. Keep the two-child demo for a clear parent-typed pair. Keep equals files off this page. Those three habits are the checkpoint before you move on. When honk appears from a Machine-typed truck variable, polymorphism did its job for this lesson and you are ready for the next topic about equals.
One last pass through the folder: one public Yard, parent and child horn bodies, parent-typed variables in main, no keyboard wait, no forced equals. Run javac Yard.java and java Yard once more on the demo you keep open. If the screen still matches the table, the many-forms call is solid and the course can move to equals on the next page.
🧠 Test Your Knowledge
Test Your Knowledge
Challenge yourself with this interactive quiz and see how well you understand the topic
📝 Instructions
- Read each question carefully
- Select the best answer for each question
- You can retake the quiz as many times as you want
- Your progress will be shown at the top