Constructores y herencia
Parte de la sección Programación Orientada a Objetos del Journey de Dart de Coddy. Lección 41 de 110.
Cuando una clase hija extiende una clase padre, se debe llamar al constructor de la clase padre para inicializar correctamente los campos heredados. Dart ofrece formas flexibles de gestionar esto mediante la lista de inicializadores utilizando super.
Si la clase principal tiene un constructor parametrizado, la clase secundaria debe llamarlo explícitamente:
class Person {
String name;
int age;
Person(this.name, this.age);
}
class Student extends Person {
String school;
Student(String name, int age, this.school) : super(name, age);
}Dart 2.17 introdujo los parámetros super, una sintaxis más limpia que reenvía los parámetros directamente al constructor principal:
class Student extends Person {
String school;
// super.name y super.age se reenvían directamente al constructor de Person
Student(super.name, super.age, this.school);
}Al trabajar con constructores con nombre, especificas qué constructor padre llamar:
class Employee extends Person {
String department;
Employee(super.name, super.age, this.department);
Employee.intern(String name, this.department) : super(name, 18);
}La regla clave es simple: la clase principal debe estar completamente inicializada antes de que la clase secundaria agregue sus propias propiedades. Tanto si usas la llamada tradicional super() como los parámetros super más recientes, Dart garantiza que la cadena de herencia se construya correctamente desde la clase principal hasta la secundaria.
Desafío
FácilConstruyamos un sistema de inventario de productos que demuestre cómo funcionan los constructores con la herencia. Crearás una jerarquía en la que distintos tipos de productos extienden una clase de producto base, y cada uno requiere una inicialización adecuada mediante constructores padre.
Organizarás tu código en dos archivos:
product.dart: Define aquí tu jerarquía de productos:- Una clase
Productcon las propiedadesString nameydouble price, un constructor que recibe ambos valores y un métodoinfo()que imprime[name]: $[price] - Una clase
Bookque extiendeProducty añade una propiedadString author. Usa parámetros super para reenviarnameypriceal constructor padre - Una clase
Electronicsque extiendeProducty añade una propiedadint warranty(en meses). Usa la llamada tradicionalsuper()en la lista de inicialización para pasar valores al padre
- Una clase
main.dart: Importa tu archivo de productos y demuestra ambos enfoques de herencia de constructores:- Crea un
Bookcon el nombre'Dart Essentials', el precio29.99y el autor'Jane Smith' - Llama a su método
info()y después imprimeAuthor: [author] - Imprime una línea vacía
- Crea un
Electronicscon el nombre'Wireless Mouse', el precio45.50y la garantía24 - Llama a su método
info()y después imprimeWarranty: [warranty] months
- Crea un
Ambas clases hijas heredan el método info() de Product sin necesidad de sobrescribirlo. La diferencia clave está en cómo llaman al constructor padre: Book usa la sintaxis más sencilla de parámetros super, mientras que Electronics usa el enfoque tradicional con super() en la lista de inicialización.
Salida esperada:
Dart Essentials: $29.99
Author: Jane Smith
Wireless Mouse: $45.5
Warranty: 24 monthsPruébalo tú mismo
import 'product.dart';
void main() {
// TODO: Crear un Book con:
// - name: 'Dart Essentials'
// - price: 29.99
// - author: 'Jane Smith'
// TODO: Llamar al método info() del book
// TODO: Imprimir "Author: [author]"
// TODO: Imprimir una línea vacía
// TODO: Crear un Electronics con:
// - name: 'Wireless Mouse'
// - price: 45.50
// - warranty: 24
// TODO: Llamar al método info() del electronics
// TODO: Imprimir "Warranty: [warranty] months"
}
Esta lección incluye un breve cuestionario. Empieza la lección para responderlo y registrar tu progreso.
Todas las lecciones de Programación Orientada a Objetos
1Fundamentos de POO
Archivos externosLibrerías e importacionesIntroducción a la POOClases vs. ObjetosLa palabra clave thisMétodosVariables de instanciaConceptos básicos de constructoresResumen - Calculadora sencilla4Seguridad de nulos
Introducción a la seguridad de nulosNulables vs No nulablesLos operadores ? y !Palabra clave Late y Null SafetyOperadores Null-awareNull Safety en clasesResumen - Sistema de perfil de usuario7Clases abstractas e interfaces
Clases abstractasMétodos abstractosInterfaces en DartInterfaces implícitasImplementar vs. ExtenderInterfaces múltiplesRepaso - Calculadora de figuras10Colecciones y Genéricos
Visión general de List, Set y MapColecciones con seguridad de tiposClases genéricasMétodos genéricosRestricciones genéricasIterable e IteratorResumen - Almacenamiento genérico2Constructores en Dart
Constructor por defectoConstructores nombradosListas de inicializaciónConstructores constantesConstructores de fábricaConstructores de redireccionamientoResumen - Constructor de formas5Encapsulamiento
Miembros públicos vs. privadosLa convención del prefijo _Privacidad a nivel de libreríaProfundidad en Getters y SettersOcultamiento de informaciónResumen - Registros de estudiantes8Mixins
Introducción a los MixinsCreación de MixinsUso de múltiples MixinsPalabra clave on en MixinsMixin vs HerenciaMixin vs InterfazResumen - Sistema Animal11Métodos especiales
Sobrescritura de toString()Sobrescritura de hashCode y ==Interfaz ComparableMétodo call()Sobrescritura de noSuchMethodResumen - Colección personalizada14Patrones de diseño Parte 1
Introducción a los patrones de diseñoPatrón SingletonPatrón FactoryPatrón ObserverPatrón Strategy3Propiedades de clase
Miembros de instancia vs. estáticosCampos Final y ConstVariables LateMétodos y campos estáticosGetters y SettersResumen - Gestor de cuentas bancarias6Herencia
Herencia básicaLa palabra clave superSobrescritura de métodosLa anotación @overrideLa palabra clave final en clasesConstructores y herenciaResumen - Jerarquía de empleados9Polimorfismo
Fundamentos del polimorfismoPolimorfismo mediante interfacesComprobación de tipos en tiempo de ejecuciónLos operadores is y asPalabra clave covariantResumen - Procesador de pagos12POO Asíncrona
Futures y async/awaitFundamentos de StreamsStream ControllersConstructores asíncronosAsincronía en métodos de claseRepaso - Data Fetcher15Patrones de diseño Parte 2
Patrón CommandPatrón AdapterPatrón DecoratorPatrón Template MethodPatrón StatePatrón CompositePatrón RepositoryPractica por tu cuenta: Compilador de Dart online