- Create a subclass with
extendsandsuper - Override a method with
@Override - Explain polymorphism and check a type with
instanceof
A company has ordinary employees and managers. Both have a name and a salary, but a manager also gets a bonus. Instead of writing a Manager class from scratch and repeating all of Employee's code, we can say: “A manager is an employee too, just a little different.” That is what inheritance is for.
extends and super
Writing class Manager extends Employee says that Manager inherits from Employee: the subclass receives the fields and methods of the superclass. A subclass constructor must first call the parent's constructor with super(...). And super.salary() calls the parent class's version of a method.
public class Main {
public static void main(String[] args) {
Employee e = new Employee("Nigar", 1200);
Manager m = new Manager("Rashad", 2000, 500);
System.out.println(e.describe());
System.out.println(m.describe());
System.out.println(m.getName() + " earns " + m.salary());
}
}
class Employee {
protected String name;
protected double baseSalary;
Employee(String name, double baseSalary) {
this.name = name;
this.baseSalary = baseSalary;
}
String getName() { return name; }
double salary() { return baseSalary; }
String describe() {
return name + ": " + salary() + " AZN";
}
}
class Manager extends Employee {
private double bonus;
Manager(String name, double baseSalary, double bonus) {
super(name, baseSalary);
this.bonus = bonus;
}
@Override
double salary() {
return super.salary() + bonus;
}
}Nigar: 1200.0 AZN Rashad: 2500.0 AZN Rashad earns 2500.0
Managerdoes not definegetName()ordescribe(), yet they work — they are inherited from the parent.- The
salary()method is overridden: same name and parameters, but new behaviour. - Notice:
describe()is written in the parent, but for the manager it showed 2500. When it callssalary(), the version from the object's actual class runs. protectedfields are visible to subclasses but not to outside code (from other packages).
Polymorphism
Polymorphism (“many forms”) means that a variable of a parent type can refer to an object of any subclass, and when a method is called, the version from the object's actual class runs. Below, a Shape array holds circles and rectangles, and the loop calls area() without caring which is which — each shape calculates its area in its own way.
public class Main {
static double round2(double x) {
return Math.round(x * 100) / 100.0;
}
public static void main(String[] args) {
Shape[] shapes = { new Circle(1), new Rectangle(3, 4), new Circle(2) };
double total = 0;
for (Shape s : shapes) {
System.out.println(s.name() + ": " + round2(s.area()));
total += s.area();
}
System.out.println("Total: " + round2(total));
}
}
class Shape {
String name() { return "Shape"; }
double area() { return 0; }
}
class Circle extends Shape {
private double r;
Circle(double r) { this.r = r; }
@Override String name() { return "Circle"; }
@Override double area() { return Math.PI * r * r; }
}
class Rectangle extends Shape {
private double w, h;
Rectangle(double w, double h) { this.w = w; this.h = h; }
@Override String name() { return "Rectangle"; }
@Override double area() { return w * h; }
}Circle: 3.14 Rectangle: 12.0 Circle: 12.57 Total: 27.71
Circle class — π · r². Pick the other shapes too: each of them could become its own subclass.The power of polymorphism is that if you add a Triangle class tomorrow, the loop in main will not need to change at all. The code depends on the general type (Shape), not on the specific classes. This is how large programs grow.
Checking types with instanceof
Sometimes you need to know an object's specific type. The expression o instanceof String s checks whether o is a String and, if it is, puts it straight into a String variable named s. This form (pattern matching) has been available since Java 16.
public class Main {
public static void main(String[] args) {
Object[] things = { "Baku", 42, new Dog("Rex"), 3.5 };
for (Object o : things) {
if (o instanceof String s) {
System.out.println("String of length " + s.length());
} else if (o instanceof Dog d) {
d.bark();
} else {
System.out.println("Something else: " + o);
}
}
}
}
class Dog {
private String name;
Dog(String name) { this.name = name; }
void bark() { System.out.println(name + " says Woof!"); }
}String of length 4 Something else: 42 Rex says Woof! Something else: 3.5
Key points
class B extends A—BinheritsA's fields and methods; in Java a class can extend only one class.super(...)calls the parent's constructor, andsuper.method()calls the parent's method.@Overridemakes the compiler check that a method really replaces a parent method.- Polymorphism: a parent-type variable refers to a subclass object, and the method of the object's actual class runs.
o instanceof Type tchecks the type and immediately gives you the object in a new variable.
Check yourself
10 questions. Every correct answer earns XP.