Menu
Coddy logo textTech

Métodos abstractos

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

Un método abstracto es un método declarado dentro de una clase abstracta que no tiene cuerpo. Define la firma del método pero deja la implementación a cada subclase. Cualquier clase que extienda la clase abstracta debe sobrescribir todos los métodos abstractos, o también será abstracta.

abstract class Animal {
  // Método abstracto - sin cuerpo, debe ser implementado por las subclases
  String makeSound();

  // Método concreto - tiene un cuerpo, compartido por todas las subclases
  void breathe() {
    print('Breathing...');
  }
}

class Dog extends Animal {
  @override
  String makeSound() {
    return 'Woof!';  // Debe proporcionar una implementación
  }
}

class Cat extends Animal {
  @override
  String makeSound() {
    return 'Meow!';  // Implementación diferente, misma firma
  }
}

Si una subclase olvida implementar un método abstracto, Dart te dará un error de compilación. Este es el punto principal: los métodos abstractos imponen un contrato. Se garantiza que cada subclase tenga ese método, por lo que puedes llamarlo de forma segura en cualquier instancia del tipo abstracto.

// Puedes usar el tipo abstracto como un tipo de variable
Animal a = Dog();
print(a.makeSound());  // ¡Guau!

Animal b = Cat();
print(b.makeSound());  // ¡Miau!

Los métodos abstractos son diferentes de los métodos concretos en una clase abstracta. Los métodos concretos tienen un cuerpo y se heredan tal cual. Los métodos abstractos no tienen cuerpo y deben ser sobrescritos.

Puedes mezclar ambos en la misma clase abstracta para compartir cierto comportamiento mientras obligas a las subclases a definir el suyo propio para otros.

CaracterísticaMétodo abstractoMétodo concreto
Tiene cuerpoNo
Debe sobrescribirseNo
PropósitoImponer contratoCompartir comportamiento
DóndeSolo en clase abstractaCualquier clase
challenge icon

Desafío

Fácil

Vamos a construir una calculadora de formas que demuestre los métodos abstractos en acción. Definirás una clase abstracta con métodos abstractos que cada forma debe implementar de manera diferente, y luego usarás esas formas a través de una interfaz común.

Organizarás tu código en cuatro archivos:

  • shape.dart: Define una clase abstracta Shape con un campo final color (String) y un constructor que lo inicialice. Declara dos métodos abstractos: double area() y double perimeter(). También añade un método concreto describe() que imprima A [color] shape with area: [area] and perimeter: [perimeter]. Debido a que area() y perimeter() son abstractos, cada subclase proporcionará su propio cálculo, pero describe() funciona para todas ellas sin ser sobrescrito.
  • circle.dart: Crea una clase Circle que extienda de Shape. Tiene un campo final radius (double). Su constructor toma color y radius y pasa color a super. Implementa area() para que devuelva 3.14 * radius * radius y perimeter() para que devuelva 2 * 3.14 * radius.
  • rectangle.dart: Crea una clase Rectangle que extienda de Shape. Tiene campos final width y height (ambos double). Su constructor toma color, width y height y pasa color a super. Implementa area() para que devuelva width * height y perimeter() para que devuelva 2 * (width + height).
  • main.dart: Importa todos los archivos. Crea un Circle con color 'red' y radio 5.0, y un Rectangle con color 'blue', ancho 4.0 y alto 6.0. Llama a describe() en cada forma. Luego crea una List<Shape> que contenga ambas formas, recorre la lista e imprime Area: [area] para cada forma.

Salida esperada:

A red shape with area: 78.5 and perimeter: 31.400000000000002
A blue shape with area: 24.0 and perimeter: 20.0
Area: 78.5
Area: 24.0

Hoja de referencia

Un método abstracto es un método declarado en una clase abstracta sin cuerpo. Las subclases deben sobrescribirlo para proporcionar su propia implementación.

abstract class Animal {
  // Método abstracto - sin cuerpo
  String makeSound();

  // Método concreto - tiene cuerpo
  void breathe() {
    print('Breathing...');
  }
}

Las subclases deben implementar todos los métodos abstractos:

class Dog extends Animal {
  @override
  String makeSound() {
    return 'Woof!';
  }
}

class Cat extends Animal {
  @override
  String makeSound() {
    return 'Meow!';
  }
}

Puedes usar el tipo abstracto como un tipo de variable:

Animal a = Dog();
print(a.makeSound());  // Woof!

Animal b = Cat();
print(b.makeSound());  // Meow!
CaracterísticaMétodo AbstractoMétodo Concreto
Tiene cuerpoNo
Debe sobrescribirseNo
PropósitoImponer contratoCompartir comportamiento
DóndeSolo en clase abstractaCualquier clase

Pruébalo tú mismo

import 'shape.dart';
import 'circle.dart';
import 'rectangle.dart';

void main() {
  // TODO: Crea un Circle con color 'red' y radio 5.0

  // TODO: Crea un Rectangle con color 'blue', ancho 4.0 y alto 6.0

  // TODO: Llama a describe() en el círculo

  // TODO: Llama a describe() en el rectángulo

  // TODO: Crea una List<Shape> que contenga ambas formas

  // TODO: Recorre la lista e imprime "Area: [area]" para cada forma
}
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