Menu
Coddy logo textTech

Clases abstractas

Parte de la sección Programación Orientada a Objetos del Journey de Dart de Coddy — lección 43 de 110.

Una clase abstracta es una clase que no se puede instanciar directamente. Sirve como un plano para otras clases, definiendo una estructura común que las subclases deben seguir. Se crea una utilizando la palabra clave abstract.

abstract class Shape {
  String color;
  
  Shape(this.color);
  
  void describe() {
    print('A $color shape');
  }
}

class Circle extends Shape {
  double radius;
  
  Circle(String color, this.radius) : super(color);
}

void main() {
  // Shape s = Shape('red');  // ¡Error! No se puede instanciar una clase abstracta
  var circle = Circle('blue', 5.0);
  circle.describe();  // Una forma blue
}

Las clases abstractas son útiles cuando tienes un concepto que es demasiado general para existir por sí solo. Una "Shape" es una idea, pero no puedes dibujar una forma sin saber si es un círculo, un rectángulo o un triángulo. La clase abstracta define lo que todas las formas tienen en común, mientras que las subclases concretas proporcionan los detalles específicos.

Ten en cuenta que las clases abstractas aún pueden tener métodos regulares con implementaciones (como describe()) y constructores. Las subclases heredan estos de la misma manera que con la herencia normal. La diferencia clave es simplemente que no puedes crear una instancia de la propia clase abstracta; debes usar una subclase concreta.

challenge icon

Desafío

Fácil

Vamos a construir un sistema de vehículos que demuestre cómo las clases abstractas sirven como planos para tipos más específicos. Crearás una clase base abstracta que defina lo que todos los vehículos tienen en común y luego la extenderás con tipos de vehículos concretos.

Organizarás tu código en dos archivos:

  • vehicle.dart: Define tu jerarquía de vehículos aquí:
    • Una abstract class Vehicle con una propiedad String brand y una propiedad int year. Incluye un constructor que tome ambos valores y un método displayInfo() que imprima [brand] ([year])
    • Una clase Car que extienda Vehicle y añada una propiedad int doors. Incluye un método honk() que imprima Beep beep!
    • Una clase Motorcycle que extienda Vehicle y añada una propiedad bool hasSidecar. Incluye un método revEngine() que imprima Vroom!
  • main.dart: Importa tu archivo de vehículos y demuestra cómo funcionan las clases abstractas:
    • Crea un Car con brand 'Toyota', year 2022, y doors 4
    • Llama a su método displayInfo() (heredado de Vehicle)
    • Imprime Doors: [doors]
    • Llama a su método honk()
    • Imprime una línea vacía
    • Crea una Motorcycle con brand 'Harley', year 2021, y hasSidecar false
    • Llama a su método displayInfo()
    • Imprime Has sidecar: [hasSidecar]
    • Llama a su método revEngine()

Recuerda que no puedes crear una instancia de Vehicle directamente ya que es abstracta; debes usar una de las subclases concretas. Tanto Car como Motorcycle heredan el método displayInfo() de la clase padre abstracta.

Salida esperada:

Toyota (2022)
Doors: 4
Beep beep!

Harley (2021)
Has sidecar: false
Vroom!

Hoja de referencia

Una clase abstracta es una clase que no se puede instanciar directamente. Sirve como un modelo para otras clases, definiendo una estructura común que las subclases deben seguir. Crea una usando la palabra clave abstract:

abstract class Shape {
  String color;
  
  Shape(this.color);
  
  void describe() {
    print('A $color shape');
  }
}

class Circle extends Shape {
  double radius;
  
  Circle(String color, this.radius) : super(color);
}

void main() {
  // Shape s = Shape('red');  // ¡Error! No se puede instanciar una clase abstracta
  var circle = Circle('blue', 5.0);
  circle.describe();  // A blue shape
}

Las clases abstractas pueden tener:

  • Métodos regulares con implementaciones
  • Constructores
  • Propiedades

Las subclases heredan estos miembros al igual que con la herencia normal. La diferencia clave es que no se puede crear una instancia de la propia clase abstracta; se debe utilizar una subclase concreta.

Pruébalo tú mismo

import 'vehicle.dart';

void main() {
  // TODO: Crear un Car con marca 'Toyota', año 2022 y puertas 4
  
  // TODO: Llamar a displayInfo() en el car
  
  // TODO: Imprimir "Doors: [doors]"
  
  // TODO: Llamar a honk() en el car
  
  // TODO: Imprimir una línea vacía
  
  // TODO: Crear una Motorcycle con marca 'Harley', año 2021 y hasSidecar false
  
  // TODO: Llamar a displayInfo() en la motorcycle
  
  // TODO: Imprimir "Has sidecar: [hasSidecar]"
  
  // TODO: Llamar a revEngine() en la motorcycle
}
quiz iconPonte a prueba

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