Datos de instancia vs. estáticos
Parte de la sección Programación Orientada a Objetos del Journey de C# de Coddy — lección 15 de 70.
Ahora que entiendes los miembros estáticos, aclaremos cuándo usar datos de instancia frente a datos estáticos. Esta decisión define cómo tu clase almacena y comparte la información.
Los datos de instancia pertenecen a cada objeto individualmente. Cada objeto obtiene su propia copia, y los cambios en un objeto no afectan a los demás:
public class BankAccount
{
public string Owner { get; set; } // Instancia: única por cuenta
public decimal Balance { get; set; } // Instancia: única por cuenta
}Cada BankAccount tiene su propio titular y saldo. Esto tiene sentido porque diferentes cuentas contienen diferentes cantidades para diferentes personas.
Los datos estáticos pertenecen a la clase misma y se comparten entre todas las instancias:
public class BankAccount
{
public static decimal InterestRate = 0.05m; // Estático - igual para todos
public static int TotalAccounts = 0; // Estático - rastrea todas las cuentas
public string Owner { get; set; }
public decimal Balance { get; set; }
}La tasa de interés se aplica por igual a cada cuenta, por lo que tiene sentido como static. El contador total de cuentas realiza un seguimiento de la información a nivel de clase, no de los datos de cuentas individuales.
Una regla simple: si los datos describen un objeto específico, hágalos de instancia. Si describen la clase en su conjunto o deben compartirse, hágalos estáticos. Mezclarlos de forma incorrecta provoca errores donde los datos cambian inesperadamente entre objetos o no están accesibles cuando se necesitan.
Desafío
FácilVamos a construir un rastreador de sesiones de juego que demuestre la diferencia entre los datos que pertenecen a jugadores individuales frente a los datos compartidos en todo el juego.
Crearás dos archivos para organizar tu código:
Player.cs: Define una clasePlayeren el espacio de nombresGameSession. Cada jugador tiene su propioUsername(string) yScore(int); estos son únicos para cada jugador. La clase también debe rastrear información que se aplica a todos los jugadores: un campo estáticoGameName(string) que almacena el nombre del juego que todos están jugando, y un campo estáticoTotalPlayers(int) que cuenta cuántos jugadores se han unido. Incluye un constructor que reciba el nombre de usuario y la puntuación inicial, e incremente automáticamente el recuento total de jugadores. Añade un método estáticoSetGameName(string name)para configurar el nombre del juego.Program.cs: En tu archivo principal, configura el juego y crea jugadores basados en la entrada. Primero establece el nombre del juego, luego crea dos jugadores y muestra su información individual junto con los datos compartidos del juego.
Recibirás cinco entradas:
- El nombre del juego
- El nombre de usuario del primer jugador
- La puntuación inicial del primer jugador
- El nombre de usuario del segundo jugador
- La puntuación inicial del segundo jugador
Imprime la salida en este formato:
Game: {GameName}
Player: {Username}, Score: {Score}
Player: {Username}, Score: {Score}
Total Players: {TotalPlayers}Por ejemplo, si las entradas son BattleArena, DragonSlayer, 1500, ShadowNinja, y 2200, la salida debería ser:
Game: BattleArena
Player: DragonSlayer, Score: 1500
Player: ShadowNinja, Score: 2200
Total Players: 2Piensa detenidamente qué datos deben basarse en instancias (diferentes para cada jugador) y cuáles deben ser estáticos (compartidos por todos los jugadores). El nombre del juego y el recuento total de jugadores describen la sesión en su conjunto, mientras que el nombre de usuario y la puntuación son únicos para cada individuo.
Hoja de referencia
Usa datos de instancia para propiedades que son únicas para cada objeto:
public class BankAccount
{
public string Owner { get; set; } // Cada cuenta tiene su propio titular
public decimal Balance { get; set; } // Cada cuenta tiene su propio saldo
}Usa datos estáticos para propiedades compartidas entre todas las instancias de una clase:
public class BankAccount
{
public static decimal InterestRate = 0.05m; // Lo mismo para todas las cuentas
public static int TotalAccounts = 0; // Realiza un seguimiento de todas las cuentas
public string Owner { get; set; }
public decimal Balance { get; set; }
}Regla de decisión: Si los datos describen un objeto específico, usa datos de instancia. Si describen la clase en su conjunto o deben compartirse, usa datos estáticos.
Pruébalo tú mismo
using System;
namespace GameSession
{
class Program
{
public static void Main(string[] args)
{
// Leer las entradas
string gameName = Console.ReadLine();
string username1 = Console.ReadLine();
int score1 = Convert.ToInt32(Console.ReadLine());
string username2 = Console.ReadLine();
int score2 = Convert.ToInt32(Console.ReadLine());
// TODO: Establecer el nombre del juego usando el método estático
// TODO: Crear dos objetos Player con los datos de entrada
// TODO: Imprimir la salida en el formato requerido
// Juego: {GameName}
// Jugador: {Username}, Puntuación: {Score}
// Jugador: {Username}, Puntuación: {Score}
// Total de jugadores: {TotalPlayers}
}
}
}
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 OOP
Archivos externosNamespaces y directivasIntro a clases y objetosLa palabra clave 'this'Métodos y parámetrosCampos vs PropiedadesConstructoresInicializadores de objetosResumen - Calculadora simple4Herencia
Sintaxis básica de herencia (:)La palabra clave 'base'Palabras clave Virtual y OverrideClases selladas (Sealed)La clase base 'object'Resumen: Jerarquía de empleados7Características avanzadas
Sobrecarga de operadoresIndexadores (this[])Sobrescritura de ToString()Métodos de extensiónResumen - Lista personalizada10Patrones de diseño - Parte 1
Introducción a los patrones de diseñoSingleton Thread-SafePatrón FactoryPatrón Observer (Eventos)Patrón Strategy2Propiedades y miembros estáticos
Propiedades autoimplementadasPropiedades de solo lectura y escrituraCampos y métodos estáticosClases estáticasMiembros con cuerpo de expresión5Polimorfismo e Interfaces
Polimorfismo: Compilación vs. EjecuciónInterfaz vs. Clase AbstractaInterfaces MúltiplesInterfaces ExplícitasUpcasting y DowncastingRepaso: Calculadora de Figuras8Conceptos avanzados de POO
Composición sobre herenciaGenéricos (clases y métodos)Delegados y eventosAtributos y ReflexiónIDisposable y la sentencia usingFundamentos de Inyección de dependencias11Patrones de diseño, parte 2
Patrón CommandPatrón AdapterPatrón DecoratorPatrón Template MethodPatrón StatePatrón Composite3Arquitectura de clases
Datos de instancia vs. estáticosPalabras clave 'readonly' y 'const'Campos de respaldoResumen - Gestor de cuentas bancarias6Encapsulamiento
Modificadores de accesoPropiedades para el encapsulamientoImplementación de ocultamiento de datosPatrones de inmutabilidadRepaso - Registros de estudiantes