Métodos y campos estáticos
Parte de la sección Programación Orientada a Objetos del Journey de Dart de Coddy — lección 20 de 110.
Ahora que entiendes la diferencia entre los miembros de instancia y estáticos, exploremos cómo usar métodos y campos estáticos de manera efectiva. Los miembros estáticos son perfectos para la funcionalidad que pertenece al concepto de clase en sí mismo, en lugar de a objetos individuales.
Los campos estáticos almacenan datos compartidos entre todas las instancias. Los usos comunes incluyen contadores, valores de configuración o datos almacenados en caché:
class MathHelper {
static const double pi = 3.14159;
static int calculationCount = 0;
static double circleArea(double radius) {
calculationCount++;
return pi * radius * radius;
}
}
print(MathHelper.circleArea(5)); // 78.53975
print(MathHelper.circleArea(3)); // 28.27431
print(MathHelper.calculationCount); // 2Observa que llamas a los métodos estáticos directamente en el nombre de la clase, no en una instancia. La clase MathHelper funciona como una utilidad; nunca necesitas crear un objeto MathHelper.
Una regla importante: los métodos estáticos no pueden acceder a los miembros de instancia directamente. No tienen acceso a this porque no están vinculados a ningún objeto específico:
class Counter {
int value = 0; // Campo de instancia
static int total = 0; // Campo estático
void increment() {
value++; // OK - el método de instancia accede al campo de instancia
total++; // OK - el método de instancia puede acceder al campo estático
}
static void reset() {
total = 0; // OK - el método estático accede al campo estático
// value = 0; // ¡Error! No se puede acceder al campo de instancia
}
}Usa miembros estáticos cuando la funcionalidad no dependa del estado del objeto: las funciones de utilidad, el seguimiento de fábricas o las constantes compartidas son candidatos ideales.
Desafío
FácilVamos a construir una clase de utilidad para operaciones de cadenas que demuestre cómo los métodos y campos estáticos trabajan juntos para proporcionar una funcionalidad útil sin necesidad de crear objetos.
Crearás dos archivos para organizar tu código:
string_utils.dart: Define una claseStringUtilsque sirva como ayudante de utilidad. Tu clase debe tener:- Un
static const String defaultSeparatorestablecido en'-' - Un
static int operationCountque comience en0para rastrear cuántas operaciones se han realizado - Un método estático
reverse(String text)que incrementeoperationCounty devuelva la cadena invertida - Un método estático
join(String first, String second)que incrementeoperationCounty devuelva las dos cadenas unidas condefaultSeparator - Un método estático
countVowels(String text)que incrementeoperationCounty devuelva el recuento de vocales (a, e, i, o, u - sin distinguir entre mayúsculas y minúsculas) - Un método estático
getStats()que devuelva una cadena que muestre el total de operaciones realizadas
- Un
main.dart: Importa tu clase de utilidad y usa sus métodos estáticos:- Llama a
reverse()con'hello'e imprime el resultado - Llama a
join()con'dart'y'lang'e imprime el resultado - Llama a
countVowels()con'Programming'e imprimeVowels: [count] - Imprime las estadísticas usando
getStats()
- Llama a
Recuerda llamar a todos los métodos directamente sobre el nombre de la clase, ya que son estáticos; no crearás ningún objeto StringUtils.
El método getStats() debe devolver este formato:
Operations performed: [operationCount]Salida esperada:
olleh
dart-lang
Vowels: 3
Operations performed: 3Hoja de referencia
Los miembros estáticos pertenecen a la clase misma en lugar de a las instancias individuales. Acceda a ellos usando el nombre de la clase, no un objeto.
Los campos estáticos almacenan datos compartidos entre todas las instancias:
class MathHelper {
static const double pi = 3.14159;
static int calculationCount = 0;
static double circleArea(double radius) {
calculationCount++;
return pi * radius * radius;
}
}
print(MathHelper.circleArea(5)); // 78.53975
print(MathHelper.calculationCount); // 1Reglas de acceso:
- Los métodos de instancia pueden acceder tanto a los miembros de instancia como a los estáticos
- Los métodos estáticos solo pueden acceder a los miembros estáticos (sin acceso a
this)
class Counter {
int value = 0; // Campo de instancia
static int total = 0; // Campo estático
void increment() {
value++; // OK - método de instancia accediendo a un campo de instancia
total++; // OK - el método de instancia puede acceder al campo estático
}
static void reset() {
total = 0; // OK - método estático accediendo a un campo estático
// value = 0; // ¡Error! No se puede acceder al campo de instancia
}
}Use miembros estáticos para funciones de utilidad, constantes compartidas, contadores o funcionalidades que no dependan del estado del objeto.
Pruébalo tú mismo
import 'string_utils.dart';
void main() {
// TODO: Llamar a reverse() con 'hello' e imprimir el resultado
// TODO: Llamar a join() con 'dart' y 'lang' e imprimir el resultado
// TODO: Llamar a countVowels() con 'Programming' e imprimir "Vowels: [count]"
// TODO: Imprimir las estadísticas usando getStats()
}
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