Polymorphism means “one call, object-specific behavior.” Caller code writes employee.getSalary() once: a full-time employee adds salary and bonus, while a part-time employee multiplies wage by hours. The loop avoids a pile of type checks because each object owns its calculation.
When objects share a parent, the common method acts as an explicit contract. Java also supports interface-based polymorphism: unrelated classes can participate as long as they implement the interface that provides the methods caller code needs.
Same method name, different implementations
This lesson uses one class per file, with interfaces in separate files too. Match each filename to its type name. Keep files from the same example in one directory, and use separate directories for different examples to avoid duplicate class names.
Employee.java
public abstract class Employee {
abstract double getSalary();
}FullTimeEmployee.java
public class FullTimeEmployee extends Employee {
private final String name;
private final double salary;
private final double bonus;
FullTimeEmployee(String name, double salary, double bonus) {
this.name = name;
this.salary = salary;
this.bonus = bonus;
}
@Override
double getSalary() {
return salary + bonus;
}
}PartTimeEmployee.java
public class PartTimeEmployee extends Employee {
private final String name;
private final double wage;
private final double hours;
PartTimeEmployee(String name, double wage, double hours) {
this.name = name;
this.wage = wage;
this.hours = hours;
}
@Override
double getSalary() {
return wage * hours;
}
}Main.java
public class Main {
public static void main(String[] args) {
Employee[] employees = {
new FullTimeEmployee("Alice", 5783, 173),
new PartTimeEmployee("Bob", 150, 15)
};
for (Employee employee : employees) {
System.out.println(employee.getSalary());
}
}
}Polymorphic payroll: one loop, different calculations
Unlock the complete interactive lab, deeper explanations, and curated reference answers.
KNOWLEDGE QUIZ
KNOWLEDGE QUIZ
Interfaces and extensibility
Report, Invoice, and GradeSheet are not necessarily the same kind of thing, but each may implement Exportable and provide export(). exportAll() depends only on that behavior. A future Receipt can join without changing the loop if it also implements Exportable. The interface makes a missing method a compile-time error, so the contract remains explicit.
Interface-based polymorphism asks what an object can do, not only what it inherits from.
Exportable.java
public interface Exportable {
String export();
}Main.java
public class Main {
static void exportAll(Exportable[] items) {
for (Exportable item : items) {
System.out.println(item.export());
}
}
}Here Main.java defines only the exportAll() helper, not an entry point yet. The exercises below add implementing classes and main().
KNOWLEDGE QUIZ
KNOWLEDGE QUIZ
Calculate different salaries in one loop
- Implement FullTimeEmployee and PartTimeEmployee.
- Both provide get_name() and getSalary().
- Put them in one list and print names and salaries with one loop.
Batch export with interface-based polymorphism
- Create unrelated Report, Invoice, and GradeSheet classes.
- Each implements export() and returns distinct text.
- Write exportAll(items) using only item.export().
- Add Receipt and prove exportAll needs no changes.