Lección 4 · 4 de 20
Herencia y @override · Dart
Herede clases en Dart con extends, pase datos al padre con super y sustituya métodos con @override, con una nómina de ejemplo.

Employee es la clase base: nombre, salario mensual y dos métodos. annualCost() multiplica por 14 (doce mensualidades más dos pagas extra) y describe() compone el texto llamando a annualCost().
`extends` crea una subclase que hereda los campos y los métodos de la base. En Manager, el constructor usa parámetros super (super.name, super.monthlySalary): pasan esos argumentos directamente al constructor de Employee, sin repetirlos. Intern lo hace a la manera clásica, con : super(name, 900) en la lista de inicialización, y fija así un salario de 900.
`@override` marca un método que sustituye al heredado. No es obligatorio, pero el analizador avisa si el nombre no coincide con ninguno de la base y deja claro qué se cambia. Manager.annualCost() reutiliza el cálculo original con super.annualCost() y le suma el bonus; describe() hace lo mismo con el texto.
Lo interesante está en main: la lista staff es de tipo List<Employee>, pero cada objeto usa su versión de los métodos. describe() solo está escrito en Employee y, aun así, para Luis llama al annualCost() de Manager y para Marta al de Intern. Eso es el polimorfismo. runtimeType muestra la clase real del objeto, e is confirma que un Intern también es un Employee.
Código · 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}');}Salida · 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
Para recordar
extendshereda todo lo de la clase base.super.campoen el constructor reenvía el argumento al padre.@overridemarca el método que se sustituye.super.metodo()llama a la versión heredada.- Cada objeto usa sus propios métodos, aunque la variable sea del tipo base.
Ejercicio
Cree una subclase Contractor con una tarifa por hora y unas horas al año, cuyo annualCost() sea tarifa por horas, y añádala a staff.