Programación Orientada a Objetos en Java: Código Ilustrativo

Programación Orientada a Objetos en Java: Código Ilustrativo

Cuando empecé con Java, me di cuenta que saber la teoría era solo el primer paso. La verdadera magia ocurre cuando escribes el código, ves cómo funcionan las cosas, te equivocas (¡y te frustras un poco!), y luego todo hace clic. Por eso, en esta entrada, vamos a aterrizar los conceptos de la Programación Orientada a Objetos con un ejemplo muy sencillo, usando mi analogía favorita: los vehículos.
¿Listo para ensuciarte las manos con código? ¡Vamos allá!


Herramientas para que practiques

  • IDE recomendado: Intellij Community (¡puedes usar cualquier editor, pero este te ayuda mucho con Java!)
  • Java versión 8 o superior
💡 Sugerencia: No tengas miedo a experimentar. Puedes modificar los ejemplos, romperlos y volverlos a armar. Así es como realmente se aprende.

1. Creando una clase base: Vehiculo

Aquí vamos a definir un “vehículo genérico”. Piensa en ello como un molde básico de cualquier vehículo real: tiene atributos (como velocidad y nivel de combustible) y comportamientos (como mostrar su estado o moverse).

// Vehiculo.java
public abstract class Vehiculo {
  private int velocidad;
  private int nivelCombustible;

  public Vehiculo(int velocidadInicial, int nivelCombustibleInicial) {
    this.velocidad = velocidadInicial;
    this.nivelCombustible = nivelCombustibleInicial;
  }

  public int getVelocidad() {
    return velocidad;
  }

  public void setVelocidad(int nuevaVelocidad) {
    if (nuevaVelocidad >= 0) {
      this.velocidad = nuevaVelocidad;
    } else {
      System.out.println("La velocidad no puede ser negativa");
    }
  }

  public int getNivelCombustible() {
    return nivelCombustible;
  }

  public void setNivelCombustible(int nuevoNivelCombustible) {
    if (nuevoNivelCombustible >= 0 && nuevoNivelCombustible <= 100) {
      this.nivelCombustible = nuevoNivelCombustible;
    } else {
      System.out.println("El nivel de combustible debe estar entre 0 y 100");
    }
  }

  public void mostrarEstado() {
    System.out.println("Velocidad: " + velocidad + " km/h");
    System.out.println("Nivel de combustible: " + nivelCombustible + "%");
  }

  public abstract void moverse();
}
💡 Info: Usamos atributos privados para proteger los datos (encapsulamiento). Y el método abstracto `moverse()` obliga a que las clases hijas digan cómo se mueven específicamente.

2. Subclases: Auto y Bicicleta

Ahora vamos a especializar nuestro molde. Cada tipo de vehículo tendrá su propia forma de moverse.

// Auto.java
public class Auto extends Vehiculo {
  public Auto(int velocidadInicial, int nivelCombustibleInicial) {
    super(velocidadInicial, nivelCombustibleInicial);
  }

  @Override
  public void moverse() {
    System.out.println("El auto está conduciendo en la carretera");
  }
}
// Bicicleta.java
public class Bicicleta extends Vehiculo {
  public Bicicleta(int velocidadInicial, int nivelCombustibleInicial) {
    super(velocidadInicial, nivelCombustibleInicial);
  }

  @Override
  public void moverse() {
    System.out.println("La bicicleta está pedaleando");
  }
}
💡 Info: ¿Ves el `@Override`? Así le decimos a Java que cada subclase personaliza el comportamiento del método abstracto.

3. Creando una interfaz: VehiculoConFrenos

A veces diferentes vehículos comparten habilidades, pero no siempre pertenecen a la misma “familia”. Aquí entra la interfaz: es como un contrato. Si lo implementas, tienes que cumplirlo.

// VehiculoConFrenos.java
public interface VehiculoConFrenos {
  void frenar();

  void arrancar();
}
⚠️ Consejo: Usa interfaces cuando varias clases necesitan comportamientos comunes, sin importar su jerarquía.

4. Implementando la interfaz en las subclases

Vamos a hacer que tanto el Auto como la Bicicleta puedan frenar y arrancar, implementando la interfaz.

// Auto.java (actualizado)
public class Auto extends Vehiculo implements VehiculoConFrenos {
  public Auto(int velocidadInicial, int nivelCombustibleInicial) {
    super(velocidadInicial, nivelCombustibleInicial);
  }

  @Override
  public void moverse() {
    System.out.println("El auto está conduciendo en la carretera");
  }

  @Override
  public void frenar() {
    System.out.println("El auto se ha detenido");
  }

  @Override
  public void arrancar() {
    System.out.println("El auto ha arrancado");
  }
}
// Bicicleta.java (actualizado)
public class Bicicleta extends Vehiculo implements VehiculoConFrenos {
  public Bicicleta(int velocidadInicial, int nivelCombustibleInicial) {
    super(velocidadInicial, nivelCombustibleInicial);
  }

  @Override
  public void moverse() {
    System.out.println("La bicicleta está pedaleando");
  }

  @Override
  public void frenar() {
    System.out.println("La bicicleta se ha detenido");
  }

  @Override
  public void arrancar() {
    System.out.println("La bicicleta ha arrancado");
  }
}

5. Clase principal: Main

Finalmente, armamos todo en una clase principal. Aquí es donde ves en acción todos los conceptos: creación de objetos, polimorfismo, encapsulamiento, interfaces…

// Main.java
public class Main {
  public static void main(String[] args) {
    Auto auto = new Auto(0, 100);
    Bicicleta bicicleta = new Bicicleta(0, 100);

    auto.arrancar();
    auto.moverse();
    auto.setVelocidad(60);
    auto.mostrarEstado();
    auto.frenar();

    bicicleta.arrancar();
    bicicleta.moverse();
    bicicleta.setVelocidad(15);
    bicicleta.mostrarEstado();
    bicicleta.frenar();
  }
}

¿Qué verás al ejecutar el programa?

El auto ha arrancado
El auto está conduciendo en la carretera
Velocidad: 60 km/h
Nivel de combustible: 100%
El auto se ha detenido
La bicicleta ha arrancado
La bicicleta está pedaleando
Velocidad: 15 km/h
Nivel de combustible: 100%
La bicicleta se ha detenido

💡 Prueba extra: Cambia los valores iniciales, añade más métodos o incluso otra subclase, como una Moto. ¡Juega y experimenta!

Código fuente

¿Prefieres copiar/pegar o ver el código completo? Puedes descargarlo en mi GitHub.


Recursos adicionales


Conclusión

Aprender POO en Java se vuelve sencillo y hasta divertido cuando ves los conceptos en acción. No temas experimentar, romper el código y buscar nuevas formas de aplicar lo que aprendes. ¡Sigue practicando!