Herencia básica
Parte de la sección Programación Orientada a Objetos del Journey de Dart de Coddy — lección 36 de 110.
La herencia permite que una clase adquiera las propiedades y métodos de otra clase. En lugar de volver a escribir el mismo código, se crea una nueva clase que se basa en una ya existente. La clase original se llama padre (o superclase), y la nueva clase es la hija (o subclase).
En Dart, usas la palabra clave extends para heredar de una clase padre:
class Animal {
String name;
Animal(this.name);
void eat() {
print('$name is eating');
}
}
class Dog extends Animal {
Dog(String name) : super(name);
void bark() {
print('$name says woof!');
}
}
void main() {
var dog = Dog('Buddy');
dog.eat(); // Heredado de Animal
dog.bark(); // Definido en Dog
}La clase Dog tiene acceso automáticamente a la propiedad name y al método eat() de Animal, además de su propio método bark(). Esto crea una relación "es-un": un Dog es un Animal.
La clase hija puede añadir nuevas propiedades y métodos, pero hereda todo lo público del padre. Ten en cuenta que los miembros privados (aquellos con _) no son accesibles directamente en subclases de diferentes librerías, aunque sigan existiendo en el objeto heredado.
Desafío
FácilVamos a construir un sistema de vehículos que demuestre cómo la herencia permite a las clases hijas reutilizar y extender la funcionalidad de la clase padre. Crearás una clase padre para vehículos generales y una clase hija para un tipo específico de vehículo.
Organizarás tu código en dos archivos:
vehicle.dart: Define tus clases aquí:- Una clase
Vehicle(el padre) con una propiedadString brand, un constructor que recibe la marca y un métodostart()que imprime'$brand engine starting...' - Una clase
Motorcycleque extiende aVehicle. Debe tener una propiedad adicionalint cc(cilindrada del motor), un constructor que reciba tanto la marca como los cc (pasando la marca al padre usandosuper), y su propio métodowheelie()que imprime'$brand is doing a wheelie!'
- Una clase
main.dart: Importa tu archivo de vehículos y demuestra la herencia en acción:- Crea un
Vehiclecon la marca'Toyota' - Llama a su método
start() - Crea una
Motorcyclecon la marca'Harley'y cc1200 - Llama al método
start()de la motocicleta (heredado de Vehicle) - Llama al método
wheelie()de la motocicleta (definido en Motorcycle) - Imprime
'Motorcycle engine: ${motorcycle.cc}cc'para mostrar la propiedad propia de la hija
- Crea un
Observa cómo la clase Motorcycle obtiene automáticamente acceso a la propiedad brand y al método start() de Vehicle, al mismo tiempo que tiene su propia propiedad única cc y el método wheelie(). Este es el poder de la herencia: construir sobre el código existente.
Salida esperada:
Toyota engine starting...
Harley engine starting...
Harley is doing a wheelie!
Motorcycle engine: 1200ccHoja de referencia
Usa la palabra clave extends para crear una clase hija que hereda de una clase padre:
class Animal {
String name;
Animal(this.name);
void eat() {
print('$name is eating');
}
}
class Dog extends Animal {
Dog(String name) : super(name);
void bark() {
print('$name says woof!');
}
}La clase hija hereda todas las propiedades y métodos públicos de la clase padre. Usa super en el constructor hijo para pasar parámetros al constructor padre.
Las clases hijas pueden añadir sus propias propiedades y métodos mientras siguen accediendo a los heredados:
var dog = Dog('Buddy');
dog.eat(); // Heredado de Animal
dog.bark(); // Definido en DogEsto crea una relación "es-un" - un Dog es un Animal.
Pruébalo tú mismo
import 'vehicle.dart';
void main() {
// TODO: Crea un Vehicle con brand 'Toyota'
// TODO: Llama al método start() del vehículo
// TODO: Crea una Motorcycle con brand 'Harley' y cc 1200
// TODO: Llama al método start() de la motocicleta (heredado de Vehicle)
// TODO: Llama al método wheelie() de la motocicleta
// TODO: Imprime 'Motorcycle engine: [cc]cc' usando la propiedad cc de la motocicleta
}
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 Repository