DMarlon Studio

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.

Dart · Inheritance and @override in DMarlon Studio: the example's code and its output in the terminal

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

  • extends inherits everything from the base class.
  • super.field in a constructor forwards the argument to the parent.
  • @override marks 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.