La Clase en POO: definición, atributos y métodos con Java

📅 Actualizado en febrero 2026 ✍️ Ángel López ⏱️ 15 min de lectura ✓ Nivel principiante

🏗️ ¿Qué es una clase en programación?

En el paradigma de la programación orientada a objetos (POO), una clase es la unidad fundamental de diseño. Funciona como un molde o plantilla que describe las características y el comportamiento que tendrán los objetos creados a partir de ella. Mientras que un objeto es algo concreto que existe en memoria durante la ejecución del programa, la clase es la definición abstracta que establece qué datos almacenará (sus atributos) y qué acciones podrá realizar (sus métodos).

Una analogía clásica y muy útil: si pensamos en la construcción de viviendas, la clase sería el plano del arquitecto. El plano describe cuántas habitaciones tendrá la casa, dónde irán las puertas y ventanas, cómo será la distribución. Pero el plano no es una casa — es la especificación a partir de la cual se construyen casas reales. Cada casa construida sería un objeto (o instancia) de esa clase.

📘 Concepto clave: en Java, todo el código se organiza dentro de clases. Incluso el método main que inicia la ejecución debe estar dentro de una clase. Java es un lenguaje puramente orientado a objetos en este sentido.

Formalmente, una clase encapsula dos elementos esenciales:

Atributos (también llamados campos, propiedades o variables de instancia): representan el estado del objeto. Por ejemplo, un objeto Coche podría tener atributos como marca, modelo, color y velocidadActual.

Métodos (también llamados operaciones o funciones miembro): representan el comportamiento del objeto. El mismo Coche podría tener métodos como acelerar(), frenar() y obtenerVelocidad().

🔄 Clase vs. objeto: la diferencia fundamental

Uno de los conceptos que más confusión genera a los principiantes es la distinción entre clase y objeto. Aunque están íntimamente relacionados, son conceptos distintos:

Característica Clase Objeto
Naturaleza Abstracta (definición) Concreta (instancia en memoria)
Existencia Tiempo de compilación Tiempo de ejecución
Cantidad Se define una vez Se pueden crear múltiples
Memoria No ocupa memoria de datos Ocupa espacio en el heap
Analogía Plano del arquitecto Casa construida

En Java, una clase se define con la palabra reservada class y un objeto se crea con el operador new. Veamos un ejemplo sencillo:

Clase y objeto básico
// Definición de la clase (el plano)
class Perro {
    String nombre;
    String raza;
    int edad;

    void ladrar() {
        System.out.println(nombre + " dice: ¡Guau!");
    }
}

// Creación de objetos (instancias concretas)
Perro miPerro = new Perro();     // Primer objeto
miPerro.nombre = "Luna";
miPerro.raza   = "Labrador";
miPerro.edad   = 3;
miPerro.ladrar();                // Luna dice: ¡Guau!

Perro otroPerro = new Perro();   // Segundo objeto
otroPerro.nombre = "Rocky";
otroPerro.raza   = "Pastor Alemán";
otroPerro.edad   = 5;
otroPerro.ladrar();              // Rocky dice: ¡Guau!

Observa cómo una única clase Perro ha permitido crear dos objetos distintos (miPerro y otroPerro), cada uno con sus propios valores de atributos. Este es el poder fundamental de las clases: ✅ definir una vez, instanciar muchas veces.

🔬 Anatomía de una clase en Java

Toda clase en Java sigue una estructura bien definida. Conocerla es fundamental para escribir código organizado y profesional:

Estructura general de una clase Java
// 1. Declaración del paquete (opcional)
package com.ciberaula.ejemplo;

// 2. Importaciones (opcional)
import java.util.ArrayList;

// 3. Declaración de la clase
public class NombreClase {

    // 4. Atributos (variables de instancia)
    private String atributo1;
    private int atributo2;

    // 5. Constantes
    public static final int MAX_VALOR = 100;

    // 6. Constructor(es)
    public NombreClase(String atributo1, int atributo2) {
        this.atributo1 = atributo1;
        this.atributo2 = atributo2;
    }

    // 7. Métodos getter y setter
    public String getAtributo1() {
        return atributo1;
    }

    public void setAtributo1(String atributo1) {
        this.atributo1 = atributo1;
    }

    // 8. Métodos de comportamiento
    public void realizarAccion() {
        System.out.println("Ejecutando acción...");
    }

    // 9. Método toString (representación como texto)
    @Override
    public String toString() {
        return "NombreClase{" + atributo1 + ", " + atributo2 + "}";
    }
}

▶️ Convenciones de nomenclatura

Java establece convenciones claras que todo programador profesional debe seguir:

Elemento Convención Ejemplo
Nombre de clase PascalCase (mayúscula inicial) CuentaBancaria
Atributos camelCase (minúscula inicial) saldoActual
Métodos camelCase + verbo calcularInteres()
Constantes UPPER_SNAKE_CASE TASA_INTERES_MAXIMA

📦 Atributos: los datos de la clase

Los atributos (también conocidos como campos o variables de instancia) representan el estado interno de un objeto. Cada objeto creado a partir de una clase posee su propia copia independiente de los atributos, lo que permite que objetos del mismo tipo almacenen datos diferentes.

🔹 Tipos de atributos

En Java existen dos categorías principales de atributos según su ámbito:

Atributos de instancia: pertenecen a cada objeto individual. Cada vez que se crea un objeto con new, se reserva memoria para estos atributos. Son los más comunes y definen el estado específico de cada objeto.

Atributos de clase (static): pertenecen a la clase en sí, no a las instancias individuales. Todos los objetos comparten el mismo valor. Son útiles para contadores, constantes de configuración o valores compartidos.

Atributos de instancia vs. de clase
public class Empleado {
    // Atributo de clase: compartido por todos los objetos
    private static int contadorEmpleados = 0;

    // Atributos de instancia: únicos para cada objeto
    private String nombre;
    private double salario;
    private int id;

    public Empleado(String nombre, double salario) {
        contadorEmpleados++;         // Se incrementa para todos
        this.id     = contadorEmpleados;
        this.nombre = nombre;
        this.salario = salario;
    }

    public static int getTotalEmpleados() {
        return contadorEmpleados;
    }
}

// Uso:
Empleado e1 = new Empleado("Ana", 35000);
Empleado e2 = new Empleado("Luis", 42000);
System.out.println(Empleado.getTotalEmpleados()); // 2

🔹 Valores por defecto de los atributos

Cuando se crea un objeto en Java, sus atributos de instancia reciben automáticamente valores por defecto si no se inicializan explícitamente:

Tipo de dato Valor por defecto
int, long, short, byte0
float, double0.0
booleanfalse
char'\u0000' (carácter nulo)
Objetos (String, arrays, etc.)null

⚠️ Precaución: las variables locales (declaradas dentro de métodos) no reciben valores por defecto. Si intentas usar una variable local sin inicializar, el compilador producirá un error. Solo los atributos de instancia y de clase tienen valores por defecto.

⚙️ Métodos: el comportamiento de la clase

Los métodos definen las acciones que puede realizar un objeto. Son bloques de código que operan sobre los atributos de la clase y proporcionan la lógica de negocio del programa. Un buen diseño de métodos es clave para crear clases reutilizables y fáciles de mantener.

▶️ Sintaxis de un método

Estructura de un método
modificadorAcceso tipoRetorno nombreMetodo(parámetros) {
    // Cuerpo del método
    return valor; // Si tipoRetorno no es void
}

// Ejemplo concreto:
public double calcularBonificacion(double porcentaje) {
    return this.salario * (porcentaje / 100.0);
}

🔹 Métodos getter y setter

Cuando los atributos son privados (como recomienda el principio de encapsulamiento), se necesitan métodos de acceso para leer y modificar sus valores. Estos métodos siguen una convención estándar en Java:

Getters y Setters con validación
public class CuentaBancaria {
    private String titular;
    private double saldo;

    // Getter: devuelve el valor del atributo
    public double getSaldo() {
        return saldo;
    }

    // Setter con validación: controla qué valores se asignan
    public void setSaldo(double nuevoSaldo) {
        if (nuevoSaldo < 0) {
            System.out.println("Error: el saldo no puede ser negativo.");
        } else {
            this.saldo = nuevoSaldo;
        }
    }

    // Getter para String
    public String getTitular() {
        return titular;
    }

    // Setter para String con validación
    public void setTitular(String titular) {
        if (titular != null && !titular.isEmpty()) {
            this.titular = titular;
        }
    }
}

💡 Buena práctica: los setters no son simples asignaciones. Su verdadero valor está en la validación: puedes impedir que un salario sea negativo, que un nombre esté vacío o que una edad supere un límite razonable. Esto protege la integridad de los datos del objeto.

🔹 Sobrecarga de métodos

Java permite definir varios métodos con el mismo nombre pero diferentes parámetros. El compilador selecciona automáticamente la versión correcta según los argumentos proporcionados en la llamada. Esto se conoce como sobrecarga de métodos (method overloading):

Sobrecarga de métodos
public class Calculadora {
    public int sumar(int a, int b) {
        return a + b;
    }

    public double sumar(double a, double b) {
        return a + b;
    }

    public int sumar(int a, int b, int c) {
        return a + b + c;
    }
}

Calculadora calc = new Calculadora();
System.out.println(calc.sumar(3, 5));        // 8     (versión int, int)
System.out.println(calc.sumar(3.5, 2.1));    // 5.6   (versión double, double)
System.out.println(calc.sumar(1, 2, 3));     // 6     (versión int, int, int)

🔧 Constructores: inicializar objetos correctamente

Un constructor es un método especial que se invoca automáticamente cuando se crea un objeto con new. Su propósito es inicializar el objeto, asegurando que sus atributos tengan valores válidos desde el primer momento. Los constructores tienen tres características distintivas:

✅ Llevan el mismo nombre que la clase. ✅ No tienen tipo de retorno (ni siquiera void). ✅ Se ejecutan automáticamente al usar new.

▶️ Constructor por defecto vs. constructor personalizado

Si no defines ningún constructor, Java proporciona automáticamente un constructor por defecto sin parámetros que inicializa los atributos con sus valores por defecto. Sin embargo, en cuanto defines al menos un constructor personalizado, el constructor por defecto ya no se genera automáticamente.

Constructores: por defecto y personalizados
public class Libro {
    private String titulo;
    private String autor;
    private int paginas;
    private double precio;

    // Constructor sin parámetros (por defecto explícito)
    public Libro() {
        this.titulo  = "Sin título";
        this.autor   = "Desconocido";
        this.paginas = 0;
        this.precio  = 0.0;
    }

    // Constructor con parámetros básicos
    public Libro(String titulo, String autor) {
        this.titulo  = titulo;
        this.autor   = autor;
        this.paginas = 0;
        this.precio  = 0.0;
    }

    // Constructor completo
    public Libro(String titulo, String autor, int paginas, double precio) {
        this.titulo  = titulo;
        this.autor   = autor;
        this.paginas = paginas;
        this.precio  = precio;
    }
}

// Tres formas de crear un Libro:
Libro l1 = new Libro();                                    // Constructor vacío
Libro l2 = new Libro("Java", "Ángel Roldán");               // Dos parámetros
Libro l3 = new Libro("Java", "Ángel Roldán", 450, 29.90);  // Completo

🔹 Encadenamiento de constructores con this()

Para evitar la duplicación de código entre constructores, se puede usar this() para llamar a otro constructor de la misma clase. La llamada a this() debe ser la primera instrucción del constructor:

Encadenamiento de constructores
public class Producto {
    private String nombre;
    private double precio;
    private int stock;

    // Constructor completo (el único que asigna directamente)
    public Producto(String nombre, double precio, int stock) {
        this.nombre = nombre;
        this.precio = precio;
        this.stock  = stock;
    }

    // Delegación al constructor completo
    public Producto(String nombre, double precio) {
        this(nombre, precio, 0);  // stock por defecto = 0
    }

    // Delegación en cadena
    public Producto() {
        this("Sin nombre", 0.0);  // Llama al constructor de 2 parámetros
    }
}

🛡️ Modificadores de acceso: público, privado y protegido

Los modificadores de acceso controlan la visibilidad de atributos y métodos desde otras clases. Son la base del encapsulamiento, uno de los cuatro pilares de la POO. Java define cuatro niveles de acceso:

Modificador Misma clase Mismo paquete Subclase Cualquier clase
private
(sin modificador)
protected
public

💡 Regla de oro del encapsulamiento: los atributos deben ser siempre private y los métodos de acceso public. Así proteges los datos internos y solo expones las operaciones que otros necesitan usar. Esta práctica se resume en: «datos privados, interfaz pública».

🚀 Instanciación: de la clase al objeto

El proceso de crear un objeto a partir de una clase se denomina instanciación. En Java, se realiza con el operador new, que ejecuta tres acciones en secuencia:

1️⃣ Reserva memoria en el heap para almacenar los atributos del nuevo objeto. 2️⃣ Ejecuta el constructor correspondiente para inicializar esos atributos. 3️⃣ Devuelve una referencia (dirección de memoria) que se almacena en la variable declarada.

Proceso de instanciación paso a paso
// Declaración: se crea la variable (referencia)
Coche miCoche;

// Instanciación: se crea el objeto en memoria
miCoche = new Coche("Toyota", "Corolla", 2024);

// Declaración + instanciación en una sola línea (lo más habitual):
Coche miCoche = new Coche("Toyota", "Corolla", 2024);

// Acceso a métodos del objeto:
miCoche.acelerar(60);
System.out.println(miCoche.getVelocidad()); // 60

⚠️ Error común: declarar una variable de tipo objeto sin usar new y luego intentar acceder a sus métodos. Esto produce un NullPointerException porque la variable contiene null (no apunta a ningún objeto en memoria).

🎯 Ejemplo integrador: sistema de gestión de productos

A continuación presentamos un ejemplo completo que integra todos los conceptos: atributos privados, constructores sobrecargados, getters y setters con validación, métodos de lógica de negocio y un atributo de clase estático.

Producto.java — Clase completa profesional
public class Producto {
    // Atributo de clase (compartido)
    private static int contadorProductos = 0;

    // Atributos de instancia (privados)
    private int    id;
    private String nombre;
    private double precio;
    private int    stock;
    private String categoria;

    // ---- Constructores ----
    public Producto(String nombre, double precio, int stock, String categoria) {
        contadorProductos++;
        this.id        = contadorProductos;
        setNombre(nombre);        // Usa setter para validar
        setPrecio(precio);
        setStock(stock);
        this.categoria = categoria;
    }

    public Producto(String nombre, double precio) {
        this(nombre, precio, 0, "General");
    }

    // ---- Getters ----
    public int getId()            { return id; }
    public String getNombre()     { return nombre; }
    public double getPrecio()     { return precio; }
    public int getStock()         { return stock; }
    public String getCategoria()  { return categoria; }

    public static int getTotalProductos() {
        return contadorProductos;
    }

    // ---- Setters con validación ----
    public void setNombre(String nombre) {
        if (nombre != null && !nombre.trim().isEmpty()) {
            this.nombre = nombre.trim();
        } else {
            throw new IllegalArgumentException("El nombre no puede estar vacío.");
        }
    }

    public void setPrecio(double precio) {
        if (precio >= 0) {
            this.precio = precio;
        } else {
            throw new IllegalArgumentException("El precio no puede ser negativo.");
        }
    }

    public void setStock(int stock) {
        if (stock >= 0) {
            this.stock = stock;
        } else {
            throw new IllegalArgumentException("El stock no puede ser negativo.");
        }
    }

    // ---- Métodos de negocio ----
    public boolean hayDisponibilidad() {
        return stock > 0;
    }

    public void vender(int cantidad) {
        if (cantidad <= 0) {
            throw new IllegalArgumentException("La cantidad debe ser positiva.");
        }
        if (cantidad > stock) {
            throw new IllegalStateException("Stock insuficiente. Disponible: " + stock);
        }
        stock -= cantidad;
        System.out.println("Vendidas " + cantidad + " unidades de " + nombre);
    }

    public double calcularValorInventario() {
        return precio * stock;
    }

    @Override
    public String toString() {
        return String.format("[%d] %s - %.2f€ (Stock: %d)", id, nombre, precio, stock);
    }
}
TestProducto.java — Programa de prueba
public class TestProducto {
    public static void main(String[] args) {
        // Crear productos
        Producto p1 = new Producto("Teclado mecánico", 79.99, 50, "Informática");
        Producto p2 = new Producto("Ratón inalámbrico", 29.99, 120, "Informática");
        Producto p3 = new Producto("Cable USB-C", 9.99);  // stock=0, categoría=General

        // Mostrar información
        System.out.println(p1);  // [1] Teclado mecánico - 79.99€ (Stock: 50)
        System.out.println(p2);  // [2] Ratón inalámbrico - 29.99€ (Stock: 120)
        System.out.println(p3);  // [3] Cable USB-C - 9.99€ (Stock: 0)

        // Vender unidades
        p1.vender(5);
        System.out.println("Valor inventario p1: " + p1.calcularValorInventario() + "€");

        // Total de productos creados
        System.out.println("Total productos: " + Producto.getTotalProductos()); // 3
    }
}

📌 Buenas prácticas en el diseño de clases

El diseño de clases bien estructuradas es una habilidad que se perfecciona con la experiencia. Estas directrices, ampliamente aceptadas en la industria, te ayudarán a crear código profesional desde el principio:

Principio de responsabilidad única: cada clase debe tener un solo propósito. Si tu clase Producto también gestiona la conexión a base de datos, algo está mal. Separa responsabilidades en clases distintas.

Atributos siempre privados: declara todos los atributos como private y proporciona getters y setters según sea necesario. No todos los atributos necesitan setter — un id generado automáticamente, por ejemplo, solo debería tener getter.

Validación en constructores y setters: nunca asumas que los datos entrantes son correctos. Valida siempre y lanza excepciones claras cuando se violen las reglas de negocio.

Implementa toString(): sobreescribir este método facilita enormemente la depuración y el registro de información (logging). Es una práctica que todo programador profesional sigue.

Nombres descriptivos: una clase llamada GestorPedidos es infinitamente mejor que GP o Clase1. Invierte tiempo en elegir buenos nombres — tu yo del futuro te lo agradecerá.

🐛 Errores frecuentes al trabajar con clases

Estos son los errores más comunes que cometen los programadores cuando empiezan a trabajar con clases en Java. Reconocerlos te ayudará a evitarlos:

🔸 Error 1: Olvidar el new al crear objetos

❌ Error: NullPointerException
Producto p;
p.getNombre();   // ¡NullPointerException! La variable p es null.

// ✅ Corrección:
Producto p = new Producto("Teclado", 79.99);
p.getNombre();   // Funciona correctamente

🔸 Error 2: Confundir = con == en objetos

❌ Error: comparar referencias en vez de contenido
Producto p1 = new Producto("Teclado", 79.99);
Producto p2 = new Producto("Teclado", 79.99);

System.out.println(p1 == p2);       // false (compara referencias)
System.out.println(p1.equals(p2));  // Depende de si equals() está sobreescrito

🔸 Error 3: Atributos públicos sin protección

❌ Error: romper el encapsulamiento
// MAL: atributos públicos permiten valores inválidos
public class Producto {
    public double precio;  // Cualquiera puede poner -999
}

Producto p = new Producto();
p.precio = -999;  // ¡Nadie lo impide!

// ✅ Corrección: atributos privados + setter con validación
private double precio;
public void setPrecio(double precio) {
    if (precio >= 0) this.precio = precio;
}

🔸 Error 4: No definir constructor por defecto cuando hay constructores personalizados

❌ Error de compilación
public class Producto {
    public Producto(String nombre) { /* ... */ }
    // No hay constructor sin parámetros
}

Producto p = new Producto();  // ¡Error de compilación!
// Java ya no genera el constructor por defecto

// ✅ Corrección: añadir constructor vacío explícitamente
public Producto() { this("Sin nombre"); }

✏️ Ejercicios prácticos

Ejercicio 1 — Clase Estudiante

Crea una clase Estudiante con los atributos privados nombre (String), matricula (String) y notaMedia (double). Implementa un constructor completo, getters, un setter para notaMedia que valide que esté entre 0 y 10, y un método estaAprobado() que devuelva true si la nota media es mayor o igual a 5. Crea dos estudiantes y muestra si están aprobados.

Solución Ejercicio 1
public class Estudiante {
    private String nombre;
    private String matricula;
    private double notaMedia;

    public Estudiante(String nombre, String matricula, double notaMedia) {
        this.nombre    = nombre;
        this.matricula = matricula;
        setNotaMedia(notaMedia);
    }

    public String getNombre()    { return nombre; }
    public String getMatricula() { return matricula; }
    public double getNotaMedia() { return notaMedia; }

    public void setNotaMedia(double nota) {
        if (nota >= 0 && nota <= 10) {
            this.notaMedia = nota;
        } else {
            throw new IllegalArgumentException("La nota debe estar entre 0 y 10.");
        }
    }

    public boolean estaAprobado() {
        return notaMedia >= 5.0;
    }

    @Override
    public String toString() {
        return matricula + " - " + nombre + " (Nota: " + notaMedia + ")";
    }

    public static void main(String[] args) {
        Estudiante e1 = new Estudiante("María López", "MAT001", 7.5);
        Estudiante e2 = new Estudiante("Carlos Ruiz", "MAT002", 4.2);

        System.out.println(e1 + " - Aprobado: " + e1.estaAprobado()); // true
        System.out.println(e2 + " - Aprobado: " + e2.estaAprobado()); // false
    }
}

Ejercicio 2 — Clase Rectangulo con sobrecarga

Crea una clase Rectangulo con atributos base y altura (ambos double). Implementa tres constructores: uno sin parámetros (cuadrado unitario 1×1), uno con un parámetro (cuadrado de lado n), y uno con dos parámetros. Añade métodos calcularArea(), calcularPerimetro() y esCuadrado(). Crea tres rectángulos y muestra sus propiedades.

Solución Ejercicio 2
public class Rectangulo {
    private double base;
    private double altura;

    public Rectangulo() {
        this(1.0, 1.0);
    }

    public Rectangulo(double lado) {
        this(lado, lado);
    }

    public Rectangulo(double base, double altura) {
        if (base <= 0 || altura <= 0) {
            throw new IllegalArgumentException("Las dimensiones deben ser positivas.");
        }
        this.base   = base;
        this.altura = altura;
    }

    public double calcularArea() {
        return base * altura;
    }

    public double calcularPerimetro() {
        return 2 * (base + altura);
    }

    public boolean esCuadrado() {
        return base == altura;
    }

    @Override
    public String toString() {
        return String.format("Rectángulo(%.1f x %.1f) - Área: %.2f",
                             base, altura, calcularArea());
    }

    public static void main(String[] args) {
        Rectangulo r1 = new Rectangulo();         // 1x1
        Rectangulo r2 = new Rectangulo(5);        // 5x5
        Rectangulo r3 = new Rectangulo(4, 7);     // 4x7

        System.out.println(r1 + " - Cuadrado: " + r1.esCuadrado());  // true
        System.out.println(r2 + " - Cuadrado: " + r2.esCuadrado());  // true
        System.out.println(r3 + " - Cuadrado: " + r3.esCuadrado());  // false
        System.out.println("Perímetro r3: " + r3.calcularPerimetro());  // 22.0
    }
}

Ejercicio 3 — Clase CuentaBancaria completa

Diseña una clase CuentaBancaria con: atributo de clase contadorCuentas, atributos de instancia numeroCuenta (autogenerado), titular y saldo. Implementa métodos depositar(), retirar() (con validación de saldo suficiente) y transferir() (que retire de una cuenta y deposite en otra). Prueba creando dos cuentas y realizando una transferencia.

Solución Ejercicio 3
public class CuentaBancaria {
    private static int contadorCuentas = 0;

    private String numeroCuenta;
    private String titular;
    private double saldo;

    public CuentaBancaria(String titular, double saldoInicial) {
        contadorCuentas++;
        this.numeroCuenta = "ES-" + String.format("%04d", contadorCuentas);
        this.titular      = titular;
        if (saldoInicial >= 0) {
            this.saldo = saldoInicial;
        } else {
            throw new IllegalArgumentException("El saldo inicial no puede ser negativo.");
        }
    }

    public CuentaBancaria(String titular) {
        this(titular, 0.0);
    }

    public String getNumeroCuenta() { return numeroCuenta; }
    public String getTitular()      { return titular; }
    public double getSaldo()        { return saldo; }

    public void depositar(double cantidad) {
        if (cantidad <= 0) {
            throw new IllegalArgumentException("La cantidad debe ser positiva.");
        }
        saldo += cantidad;
        System.out.println("Depósito de " + cantidad + "€ en " + numeroCuenta);
    }

    public void retirar(double cantidad) {
        if (cantidad <= 0) {
            throw new IllegalArgumentException("La cantidad debe ser positiva.");
        }
        if (cantidad > saldo) {
            throw new IllegalStateException("Saldo insuficiente. Disponible: " + saldo + "€");
        }
        saldo -= cantidad;
        System.out.println("Retiro de " + cantidad + "€ de " + numeroCuenta);
    }

    public void transferir(CuentaBancaria destino, double cantidad) {
        this.retirar(cantidad);
        destino.depositar(cantidad);
        System.out.println("Transferencia completada: " + numeroCuenta
                         + " → " + destino.getNumeroCuenta());
    }

    @Override
    public String toString() {
        return String.format("%s (%s) - Saldo: %.2f€",
                             numeroCuenta, titular, saldo);
    }

    public static void main(String[] args) {
        CuentaBancaria cuenta1 = new CuentaBancaria("Ana García", 1000);
        CuentaBancaria cuenta2 = new CuentaBancaria("Luis Martínez", 500);

        System.out.println("--- Estado inicial ---");
        System.out.println(cuenta1);
        System.out.println(cuenta2);

        cuenta1.transferir(cuenta2, 250);

        System.out.println("\n--- Después de la transferencia ---");
        System.out.println(cuenta1);  // Saldo: 750.00€
        System.out.println(cuenta2);  // Saldo: 750.00€
    }
}

❓ Preguntas frecuentes sobre La Clase en POO: definición, atributos y métodos con Java

Las dudas más comunes respondidas de forma clara y directa.

Una clase es una plantilla o molde que define los atributos (datos) y métodos (comportamiento) que tendrán los objetos creados a partir de ella. Es como el plano de un edificio: describe la estructura, pero no es el edificio en sí.
La clase es la definición abstracta (el plano), mientras que el objeto es una instancia concreta de esa clase (el edificio construido). Una clase se define una vez, pero se pueden crear múltiples objetos a partir de ella, cada uno con sus propios valores de atributos.
Un constructor es un método especial que se ejecuta automáticamente al crear un objeto con new. Su función es inicializar los atributos del objeto con valores válidos. Tiene el mismo nombre que la clase y no tiene tipo de retorno.
Una clase puede tener tantos constructores como se necesiten, siempre que se diferencien en el número o tipo de parámetros. Esto se llama sobrecarga de constructores y permite crear objetos de distintas maneras.
Declarar atributos como private significa que solo pueden ser accedidos desde dentro de la propia clase, no desde otras clases. Esto protege los datos internos y obliga a usar métodos getter y setter para leer o modificar los valores, lo que se conoce como encapsulamiento.
Valora este artículo

💬 Foro de discusión

¿Tienes dudas sobre La Clase en POO: definición, atributos y métodos con Java? Comparte tu pregunta con la comunidad.

¿Tienes cuenta? o comenta como invitado ↓

Todavía no hay mensajes. ¡Sé el primero en participar!