Sometimes two classes share most of their data and behavior. A manager is still a staff member, and an express package is still a package. Copying the same fields into both classes means fixing every bug twice. Inheritance lets a new class start from an existing one and add only what is different.
The class you build on is the parent (or superclass), and the new class is the child (or subclass). In Apex the parent must be marked virtual before anything can extend it:
public virtual class Vehicle {
public Integer wheels;
public String describe() {
return 'A vehicle with ' + wheels + ' wheels';
}
}
public class Truck extends Vehicle {
public Integer payload;
}
A Truck object has everything a Vehicle has, plus its own payload field. You can call truck.describe() and read truck.wheels even though Truck never declares them.
A child constructor often needs the parent to set up its part of the object first. Call the parent constructor with super(...), and make it the first line:
public virtual class Vehicle {
public Integer wheels;
public Vehicle(Integer wheels) {
this.wheels = wheels;
}
}
public class Truck extends Vehicle {
public Integer payload;
public Truck(Integer wheels, Integer payload) {
super(wheels);
this.payload = payload;
}
}
super(wheels) runs the Vehicle constructor, then the Truck constructor finishes with its own field.
Because a Truck is a Vehicle, you can store it in a Vehicle variable: Vehicle v = new Truck(6, 2000);. Through that variable you can only use what Vehicle declares, so v.wheels works but v.payload does not compile.
Forgetting virtual on the parent is a compile error. Forgetting the super(...) call is also a compile error when the parent has no constructor without parameters, because Apex cannot build the parent part of the object on its own.
The exercise editor runs your code as one anonymous block, and there every class can already be extended. Writing virtual on a class in the editor is actually a compile error (classes are by default virtual), so the starter code leaves it off and adds a comment showing how the class would look in a real org. Everything else, including extends and super, works exactly the same.
Inheritance is how Salesforce frameworks hand you shared behavior. A trigger handler framework, for example, gives you a base class, and your handler extends it to add only the logic for your object.