Variables de instancia vs. estáticas
Parte de la sección Programación Orientada a Objetos del Journey de Java de Coddy — lección 15 de 87.
Hasta ahora, cada campo que hemos creado pertenece a un objeto específico. Cada BankAccount tiene su propio balance, y cada Product tiene su propio name. Estas son variables de instancia - existen por separado para cada instancia de una clase.
Pero, ¿qué pasa si necesitas datos que se compartan entre todos los objetos? Ahí es donde entran las variables estáticas (también llamadas variables de clase). Una variable estática pertenece a la clase misma, no a ningún objeto en particular.
public class Student {
private String name; // Variable de instancia - única por estudiante
private static int totalCount; // Variable estática - compartida por todos los estudiantes
public Student(String name) {
this.name = name;
totalCount++; // Incrementa el contador compartido
}
public static int getTotalCount() {
return totalCount;
}
}Cuando creas múltiples estudiantes, cada uno tiene su propio name, pero todos comparten el mismo totalCount:
Student s1 = new Student("Alice");
Student s2 = new Student("Bob");
System.out.println(Student.getTotalCount()); // Salida: 2Observe cómo accedemos a la variable estática a través del nombre de la clase (Student.getTotalCount()) en lugar de a través de un objeto. Esto enfatiza que los miembros estáticos pertenecen a la clase, no a las instancias.
Usa variables de instancia para datos que varían entre objetos (como el nombre de un estudiante). Usa variables estáticas para datos que deben ser compartidos (como contar cuántos objetos existen).
Desafío
FácilVamos a construir un sistema de inventario de Book que realice un seguimiento tanto de los detalles individuales de los libros como del número total de libros en toda su colección utilizando variables de instancia y estáticas.
Crearás dos archivos para organizar tu código:
Book.java: Crea una clase Book que realice un seguimiento de la información individual de los libros y, al mismo tiempo, mantenga un recuento de todos los libros creados:- Una variable de instancia
title(String): única para cada libro - Una variable de instancia
price(double): única para cada libro - Una variable estática
totalBooks(int): compartida entre todos los objetos Book, que rastrea cuántos libros se han creado - Un constructor que recibe el título y el precio, e incrementa el recuento total de libros
- Un getter
getTitle()para el título - Un getter
getPrice()para el precio - Un método estático
getTotalBooks()que devuelve el número total de libros creados
- Una variable de instancia
Main.java: Crea múltiples objetos Book y demuestra cómo el contador estático rastrea todas las instancias. Recibirás tres títulos de libros y tres precios como entradas. Después de crear los tres libros, imprime cuatro líneas:- El título y el precio de cada libro en el formato:
[title]: $[price](precio formateado a 2 decimales) - El número total de libros utilizando el método estático:
Total books: [count]
- El título y el precio de cada libro en el formato:
Recibirás seis entradas en orden: title1, price1, title2, price2, title3, price3.
Recuerda acceder al método estático a través del nombre de la clase (Book.getTotalBooks()) en lugar de a través de una instancia de objeto. Para formatear los precios, utiliza String.format("%.2f", price).
Hoja de referencia
Una variable estática (también llamada variable de clase) pertenece a la clase misma y se comparte entre todas las instancias de esa clase, a diferencia de las variables de instancia que son únicas para cada objeto.
Declara una variable estática usando la palabra clave static:
public class Student {
private String name; // Variable de instancia - única por estudiante
private static int totalCount; // Variable estática - compartida por todos los estudiantes
public Student(String name) {
this.name = name;
totalCount++; // Incrementa el contador compartido
}
public static int getTotalCount() {
return totalCount;
}
}Accede a las variables y métodos estáticos a través del nombre de la clase en lugar de a través de una instancia de objeto:
Student s1 = new Student("Alice");
Student s2 = new Student("Bob");
System.out.println(Student.getTotalCount()); // Salida: 2Usa variables de instancia para los datos que varían entre objetos. Usa variables estáticas para los datos que deben compartirse entre todas las instancias.
Pruébalo tú mismo
import java.util.Scanner;
class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
// Lee las entradas para tres libros
String title1 = scanner.nextLine();
double price1 = Double.parseDouble(scanner.nextLine());
String title2 = scanner.nextLine();
double price2 = Double.parseDouble(scanner.nextLine());
String title3 = scanner.nextLine();
double price3 = Double.parseDouble(scanner.nextLine());
// TODO: Crea tres objetos Book usando las entradas anteriores
// TODO: Imprime el título y el precio de cada libro en el formato: [title]: $[price]
// Usa String.format("%.2f", price) para dar formato al precio con 2 decimales
// TODO: Imprime el número total de libros usando el método estático
// Formato: Total books: [count]
// Recuerda acceder al método estático a través del nombre de la clase: Book.getTotalBooks()
}
}
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 externosIntroducción a la OOPClases vs. ObjetosLa palabra clave thisMétodosCampos (Atributos)Método constructorSobrecarga de constructoresResumen - Calculadora simple4Herencia
Herencia básica (extends)La palabra clave superSobrescritura de métodos (@Override)Encadenamiento de constructoresLa clase ObjectHerencia simple y multinivelPor qué no hay herencia múltiple de clasesResumen - Jerarquía de empleados7Métodos especiales y la clase Object
Método toString()equals() y hashCode()Método clone()compareTo() y ComparableInterfaz ComparatorResumen - Ordenamiento personalizado2Modificadores de acceso y encapsulamiento
Visión general de los niveles de accesoMétodos Getter y SetterOcultamiento de informaciónLa palabra clave finalResumen - Gestor de cuentas bancarias5Polimorfismo
Fundamentos de sobrecarga de métodosSobrescritura de métodos (tiempo de ejecución)Upcasting y DowncastingEl operador instanceofClases y métodos abstractosResumen - Calculadora de figuras8Conceptos avanzados de POO
Composición vs. HerenciaAgregación vs. ComposiciónClases internas, anidadas y anónimasEnums y métodos de EnumRecords (Java 16+)Clases selladas (Java 17+)11Patrones de diseño - Parte 1
Introducción a los patrones de diseñoPatrón SingletonPatrón FactoryPatrón BuilderPatrón ObserverPatrón Strategy3Propiedades de clase y miembros estáticos
Variables de instancia vs. estáticasMétodos estáticosBloques estáticosConstantes (static final)Repaso - Contador y utilidad6Interfaces y Clases Abstractas
Introducción a las InterfacesImplementación de InterfacesImplementación de Múltiples InterfacesMétodos Default y Static en InterfacesClases Abstractas vs InterfacesInterfaces FuncionalesResumen - Sistema de Pagos9Genéricos
Introducción a los genéricosClases genéricasMétodos genéricosParámetros de tipo delimitadosComodines (?, extends, super)Resumen - Contenedor genérico12Patrones de diseño Parte 2
Patrón CommandPatrón AdapterPatrón DecoratorPatrón Template MethodPatrón StatePatrón CompositePatrón Iterator