Conceptos de POO en Java
Una introducción a la programación orientada a objetos en Java: encapsulación, herencia, polimorfismo y abstracción.
La programación orientada a objetos (POO) es una forma de organizar el código en torno a las cosas de tu programa, en lugar de los pasos. En vez de un largo script que opera sobre variables crudas, describes los tipos de objetos de tu dominio — un User, un Order, una BankAccount — y le das a cada uno los datos y el comportamiento que necesita. El resto del programa entonces le pide a esos objetos que hagan cosas, en lugar de manipular sus internos directamente.
Java fue construido alrededor de esta idea. Cada línea de código Java que escribes vive dentro de una clase, y una clase es el plano a partir del cual se crean los objetos. Hasta ahora has estado escribiendo código mayormente procedural dentro de main y algunos métodos estáticos auxiliares; a partir de esta parte del libro, empezarás a diseñar tus propias clases.
Clases y objetos en una oración
Una clase describe un tipo de cosa — qué datos almacena y qué puede hacer. Un objeto es una instancia específica de esa cosa.
public class Dog {
String name;
int age;
void bark() {
System.out.println(name + " says woof");
}
}
Dog d = new Dog(); // d is an object — one specific dog
d.name = "Rex";
d.bark(); // Rex says woofDog es la clase. d es un objeto. El cambio clave respecto al código procedural: un objeto agrupa estado (los campos name y age) y comportamiento (el método bark()) en una sola unidad. Puedes crear tantos objetos Dog como quieras; cada uno tiene su propia copia de name y age, y cada uno puede bark() por su cuenta. El capítulo de clases y objetos analiza esto en detalle.
Los cuatro pilares
La POO se suele enseñar alrededor de cuatro ideas. Cada una tiene un capítulo completo más adelante en esta parte del libro — lo que sigue es un recorrido de treinta segundos para que sepas hacia dónde va el camino.
Encapsulación
Mantén los datos de un objeto privados; expón el comportamiento en su lugar. El código externo llama a account.deposit(50), no a account.balance += 50. El beneficio es que la clase controla sus propios invariantes — nadie más puede ponerla en un estado incorrecto.
public class Account {
private int balance; // hidden
public void deposit(int amount) { // public behavior
if (amount <= 0) throw new IllegalArgumentException();
balance += amount;
}
}Consulta el capítulo de encapsulación.
Herencia
Una clase puede extender otra, heredando sus campos y métodos y añadiendo a ellos. Cat extends Animal reutiliza todo lo que Animal ya hace y solo especifica lo que es diferente en los gatos.
public class Animal {
void breathe() { System.out.println("inhale, exhale"); }
}
public class Cat extends Animal {
void purr() { System.out.println("rrr"); }
}
Cat c = new Cat();
c.breathe(); // inherited
c.purr(); // ownConsulta el capítulo de herencia.
Polimorfismo
La misma llamada puede hacer cosas diferentes dependiendo del objeto real en el extremo receptor. Una variable de tipo Animal podría apuntar a un Cat, un Dog o una Cow — llamar a speak() sobre ella elige el comportamiento correcto en tiempo de ejecución.
Animal a = new Cat();
a.speak(); // calls Cat's speak, even though a is typed as AnimalConsulta el capítulo de polimorfismo.
Abstracción
Define qué hace algo sin comprometerte con el cómo. Una interface Shape indica que cada figura tiene un método area(); cada figura concreta — Circle, Square — aporta su propia fórmula. El código que trabaja con figuras no necesita saber qué tipo tiene.
public interface Shape {
double area();
}Consulta el capítulo de abstracción.
Los pilares de un vistazo
| Pilar | Idea en una línea | Herramienta Java |
|---|---|---|
| Encapsulación | Ocultar datos, exponer comportamiento | Campos private + métodos públicos |
| Herencia | Reutilizar y extender otra clase | extends |
| Polimorfismo | Una llamada, comportamiento elegido en tiempo de ejecución | sobreescritura + variables de supertipo |
| Abstracción | Definir qué, no cómo | interfaces y clases abstractas |
Los pilares se superponen intencionalmente: el polimorfismo se apoya en la herencia, la abstracción se refuerza mediante la encapsulación, y así sucesivamente. Trátelos como cuatro ángulos de una sola idea — modelar tu programa como objetos que cooperan — en lugar de cuatro características separadas que memorizar.
¿Para qué molestarse?
Para un script de 20 líneas, la POO es excesiva. El beneficio aparece a medida que los programas crecen:
- Razonamiento local. Una clase
BankAccountposee sus reglas. Para entender o cambiar los depósitos, lees el métododeposit— no haces grep en el código buscandobalance +=. - Reutilización sin copiar y pegar. La herencia y la composición permiten que
SavingsAccountse construya sobreAccounten lugar de duplicarla. - Sustituibilidad. Una función que recibe una
Shapefunciona con todas las figuras que existen hoy y con todas las que añadas mañana. - Capacidad de prueba. Los objetos pequeños con responsabilidades claras son fáciles de instanciar, ejecutar y verificar.
Java está lejos de ser el único lenguaje orientado a objetos — Python, C#, Kotlin, Ruby y muchos otros comparten las mismas ideas con diferente sintaxis. Lo que aprendas en esta parte es transferible.
La POO no es el único paradigma
Incluso dentro de Java, ya has escrito código que no es estrictamente OO: métodos de utilidad estáticos, aritmética con primitivos, flujo de control simple. El Java moderno mezcla paradigmas — pipelines funcionales con streams y lambdas, datos inmutables con records, trabajo declarativo con anotaciones. La POO es la columna vertebral del lenguaje, no una jaula. Usa una clase cuando modeles algo con estado y comportamiento; recurre a un método estático cuando solo necesites un cálculo.
Un ejemplo práctico
El código completo de los fragmentos anteriores, reunido para que puedas ejecutarlo:
Qué sigue
Ahora que conoces la forma de la POO, el siguiente capítulo profundiza en sus fundamentos: cómo una definición de clase se convierte en un objeto en memoria, qué hace realmente new y en qué se diferencian las referencias a objetos de los primitivos. Continúa con Java clases y objetos.