Menu
Coddy logo textTech

Clases invocables

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

En Dart, puedes hacer que las instancias de una clase sean invocables como funciones implementando el método call(). Esto te permite usar un objeto con la sintaxis de llamada a función - usando paréntesis directamente sobre la instancia.

class Multiplier {
  final int factor;
  
  Multiplier(this.factor);
  
  int call(int value) {
    return value * factor;
  }
}

void main() {
  var double = Multiplier(2);
  var triple = Multiplier(3);
  
  print(double(5));   // 10 - llamando al objeto como una función
  print(triple(5));   // 15
}

Cuando escribes double(5), Dart invoca automáticamente el método call() con 5 como argumento. El objeto se comporta como una función mientras mantiene su estado (el campo factor).

El método call() puede tener cualquier firma: múltiples parámetros, parámetros opcionales o incluso devolver diferentes tipos:

class Greeter {
  final String greeting;
  
  Greeter(this.greeting);
  
  String call(String name, {String punctuation = '!'}) {
    return '$greeting, $name$punctuation';
  }
}

void main() {
  var hello = Greeter('Hello');
  print(hello('Alice'));              // Hello, Alice!
  print(hello('Bob', punctuation: '.')); // Hello, Bob.
}

Las clases invocables son útiles cuando necesitas un comportamiento similar al de una función combinado con estado o configuración. Se utilizan comúnmente para crear operaciones reutilizables, validadores o transformaciones que necesitan recordar ajustes entre llamadas.

challenge icon

Desafío

Fácil

¡Vamos a construir un sistema formateador de texto utilizando clases llamables (callable classes)! Crearás objetos que pueden ser llamados como funciones para transformar texto de diferentes maneras, manteniendo sus propios ajustes de configuración.

Organizarás tu código en dos archivos:

  • formatters.dart: Crea dos clases llamables que transformen texto:
    • Una clase Wrapper que envuelva el texto con un prefijo y un sufijo. Debe almacenar un String prefix y un String suffix, y cuando se llame con un parámetro String text, debe devolver el texto envuelto entre el prefijo y el sufijo.
    • Una clase Repeater que repita el texto un cierto número de veces. Debe almacenar un valor int times, y cuando se llame con un parámetro String text, debe devolver el texto repetido esa cantidad de veces con un espacio entre cada repetición.
  • main.dart: Importa tus formateadores y demuestra cómo funcionan las clases llamables:
    • Crea un Wrapper con el prefijo "[" y el sufijo "]"
    • Crea otro Wrapper con el prefijo "***" y el sufijo "***"
    • Crea un Repeater que repita 3 veces
    • Llama al primer wrapper con "Hello" e imprime el resultado
    • Llama al segundo wrapper con "Important" e imprime el resultado
    • Llama al repeater con "Go" e imprime el resultado
    • Finalmente, combínalos: llama al primer wrapper con el resultado de llamar al repeater con "Dart", e imprime el resultado

¡Observa cómo cada objeto formateador recuerda su configuración y puede ser llamado directamente con paréntesis, igual que una función!

Salida esperada:

[Hello]
***Important***
Go Go Go
[Dart Dart Dart]

Hoja de referencia

Las clases pueden hacerse invocables como funciones implementando el método call():

class Multiplier {
  final int factor;
  
  Multiplier(this.factor);
  
  int call(int value) {
    return value * factor;
  }
}

void main() {
  var double = Multiplier(2);
  print(double(5));   // 10 - calling the object like a function
}

El método call() puede tener cualquier firma con múltiples parámetros, parámetros opcionales o diferentes tipos de retorno:

class Greeter {
  final String greeting;
  
  Greeter(this.greeting);
  
  String call(String name, {String punctuation = '!'}) {
    return '$greeting, $name$punctuation';
  }
}

void main() {
  var hello = Greeter('Hello');
  print(hello('Alice'));              // Hello, Alice!
  print(hello('Bob', punctuation: '.')); // Hello, Bob.
}

Las clases invocables son útiles para crear un comportamiento similar al de una función combinado con estado o configuración.

Pruébalo tú mismo

import 'formatters.dart';

void main() {
  // TODO: Crear un Wrapper con el prefijo "[" y el sufijo "]"
  
  // TODO: Crear otro Wrapper con el prefijo "***" y el sufijo "***"
  
  // TODO: Crear un Repeater que se repita 3 veces
  
  // TODO: Llamar al primer wrapper con "Hello" e imprimir el resultado
  
  // TODO: Llamar al segundo wrapper con "Important" e imprimir el resultado
  
  // TODO: Llamar al repeater con "Go" e imprimir el resultado
  
  // TODO: Combinarlos: llamar al primer wrapper con el resultado de
  // llamar al repeater con "Dart", e imprimir el resultado
  
}
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