Lesson 4 · 4 of 20
Inheritance and @override · Dart
Inherit Dart classes with extends, pass data to the parent with super and replace methods with @override, using a payroll example.

Employee is the base class: a name, a monthly salary and two methods. annualCost() multiplies by 14 (twelve monthly payments plus two extra ones, as is common in Spain) and describe() builds the text by calling annualCost().
`extends` creates a subclass that inherits the base class's fields and methods. In Manager, the constructor uses super parameters (super.name, super.monthlySalary): they pass those arguments straight to Employee's constructor without repeating them. Intern does it the classic way, with : super(name, 900) in the initializer list, which fixes the salary at 900.
`@override` marks a method that replaces the inherited one. It is not mandatory, but the analyzer warns you if the name matches nothing in the base class, and it makes clear what is being changed. Manager.annualCost() reuses the original calculation through super.annualCost() and adds the bonus; describe() does the same with the text.
The interesting part is in main: the staff list is a List<Employee>, yet each object uses its own version of the methods. describe() is only written in Employee and still, for Luis it calls Manager's annualCost() and for Marta the Intern one. That is polymorphism. runtimeType shows the object's real class, and is confirms that an Intern is also an Employee.
Code · main.dart
class Employee { final String name; final int monthlySalary; Employee(this.name, this.monthlySalary); int annualCost() => monthlySalary * 14; // 14 payments a year String describe() => '$name: ${annualCost()} EUR/year';}class Manager extends Employee { final int bonus; // super.name passes the argument on to the parent constructor. Manager(super.name, super.monthlySalary, {required this.bonus}); @override int annualCost() => super.annualCost() + bonus; @override String describe() => '${super.describe()} (incl. bonus $bonus)';}class Intern extends Employee { Intern(String name) : super(name, 900); @override int annualCost() => monthlySalary * 6; // six-month contract}void main() { final staff = [Employee('Ana', 2400), Manager('Luis', 3800, bonus: 6000), Intern('Marta')]; for (final person in staff) print(person.describe()); // its own annualCost() print('Payroll: ${staff.fold(0, (sum, p) => sum + p.annualCost())} EUR'); print('${staff[2].runtimeType} is Employee: ${staff[2] is Employee}');}Output · dart run main.dart
Ana: 33600 EUR/year Luis: 59200 EUR/year (incl. bonus 6000) Marta: 5400 EUR/year Payroll: 98200 EUR Intern is Employee: true
Key points
extendsinherits everything from the base class.super.fieldin a constructor forwards the argument to the parent.@overridemarks the method being replaced.super.method()calls the inherited version.- Each object uses its own methods, even through a base-class variable.
Exercise
Create a Contractor subclass with an hourly rate and yearly hours, whose annualCost() is rate times hours, and add one to staff.