virtual, override and super
Classes & objects · Intermediate · 18 min · Runs in your Salesforce Developer org · Free
Extend a provided `Vehicle` class with a `Car` subclass that overrides `describe()`. The override must call `super.describe()` to read the base label, then wrap it as `Car (from Vehicle)`. Keep the given class names so the hidden tests can find them.
Lesson
Why this matters
In Apex, a method on a base class is sealed by default. Nothing on a subclass can replace it. If you want a subclass to swap in its own behaviour and still reuse the base work, three keywords have to line up: virtual on the base method, override on the subclass, and super to call back into the base.
The smallest working example
public virtual class Vehicle {
public virtual String describe() {
return 'Vehicle';
}
}
public class Car extends Vehicle {
public override String describe() {
return 'Car (from ' + super.describe() + ')';
}
}
new Car().describe() returns Car (from Vehicle).
Name the parts
- **
virtual** on the base method says "a subclass is allowed to replace me". - **
extends** on the subclass links the two classes. - **
override** on the subclass method says "I am replacing the base version". Do not addvirtualagain. - **
super.describe()** calls the base version from inside the override, so you can wrap it instead of repeating it.
A common wrong version
public class Car extends Vehicle {
public virtual String describe() {
return 'Car (from ' + describe() + ')';
}
}
Two bugs. virtual on the subclass should be override, so the compiler rejects the class. And describe() on its own calls itself, which would loop forever if it compiled. The call to the base must be super.describe().
The fix
Use override, then build the label from super.describe():
public override String describe() {
return 'Car (from ' + super.describe() + ')';
}
Now you try
Fill in the Car body in the starter. The base Vehicle class is already provided; do not change it. The hidden tests call both new Car() and a Vehicle-typed reference pointing at a Car.
Learn more
The challenge
Finish the Car subclass so describe() wraps the base label.
Examples:
new AS_1860C37D10D4_Vehicle().describe()buildsVehiclenew AS_1860C37D10D4_Car().describe()buildsCar (from Vehicle)- A
Vehicle-typed variable holding aCarstill runs the override
Requirements:
baseReturnsVehicleshould pass: the providedVehicleon its own still returnsVehicle.carOverridesWithSupershould pass:new Car().describe()returnsCar (from Vehicle)by callingsuper.describe().dynamicDispatchHitsOverrideshould pass: aVehiclevariable holding aCarruns the override.baseAndChildAreDistinctshould pass:VehicleandCarreturn different labels.
Starter code
public class AS_1860C37D10D4_Car extends AS_1860C37D10D4_Vehicle {
}
Related drills
- Interface with two implementations
- Constructor chaining with this(...)
- finally and several catch blocks
You write the Apex yourself. ApexSensei runs it and tells you what passed and what did not.
‹ Interface with two implementations · Constructor chaining with this(...) ›