Introducción a la Programación Orientada a Objetos
Java es un lenguaje de programación completamente orientado a objetos (POO), donde todo se modela como objetos. Esta aproximación se basa en la interacción entre objetos para resolver problemas, facilitando el diseño, mantenimiento y extensión de aplicaciones complejas.
Diferencias entre Enfoque Orientado a Objetos y Orientado a Procesos
El enfoque orientado a procesos se centra en la secuencia de pasos para realizar una tarea. Por ejemplo, lavar ropa manualmente requiere seguir instrucciones específicas para cada tipo de prenda, lo que complica la escalabilidad.
En cambio, el enfoque orientado a objetos descompone el problema en entidades (objetos) como persona, ropa, detergente y lavadora. Cada objeto tiene responsabilidades y se comunican entre sí. El usuario no necesita conocer los detalles internos de la lavadora, solo interactúa con ella a través de una interfaz.
Definición y Uso de Clases
Una clase es una plantilla que describe las características (atributos) y comportamientos (métodos) de un objeto. En Java, se utiliza la palabra clave class para definir una clase.
Estructura de una Clase
Los miembros de una clase incluyen variables de instancia (atributos) y métodos. Por ejemplo, para modelar un vehículo:
public class Vehiculo {
// Atributos
public String marca;
public int modelo;
public String color;
// Métodos
public void mostrarDetalles() {
System.out.println("Marca: " + marca + ", Modelo: " + modelo + ", Color: " + color);
}
}
Convenciones: el nombre de la clase usa CamelCase, los miembros son públicos por simplicidad y los métodos no son estáticos en esta fase.
Instanciación de Objetos
La instanciación crea un objeto a partir de una clase usando el operador new. El objeto resultante es una referencia que almacena datos en memoria.
// Crear una instancia de Vehiculo
Vehiculo miVehiculo = new Vehiculo();
miVehiculo.marca = "Toyota";
miVehiculo.modelo = 2023;
miVehiculo.color = "Rojo";
miVehiculo.mostrarDetalles(); // Salida: Marca: Toyota, Modelo: 2023, Color: Rojo
Una clase puede generar múltiples objetos independientes, cada uno con su propio espacio de memoria para sus atributos.
Uso de la Referencia this
La referencia this apunta al objeto actual que ejecuta un método. Se utiliza para resolver ambigüedades cuando los nombres de parámetros coinciden con los atributos, y para acceder a miembros del objeto dentro de métodos.
public class Producto {
private String nombre;
private double precio;
public Producto(String nombre, double precio) {
this.nombre = nombre; // 'this' diferencia el atributo del parámetro
this.precio = precio;
}
public void mostrarInfo() {
System.out.println("Producto: " + this.nombre + ", Precio: " + this.precio);
}
}
Características de this: es del tipo de la clase, solo disponible en métodos de instancia, y es un parámetro implícito pasado por el compilador.
Inicialización de Objetos: Métodos Constructores
Los métodos constructores inicializan los atributos de un objeto al momento de su creación. Son especiales porque tienen el mismo nombre que la clase y no tienen valor de retorno.
public class Persona {
private String nombre;
private int edad;
private String ocupacion;
// Constructor sin argumentos
public Persona() {
this.nombre = "Desconocido";
this.edad = 0;
this.ocupacion = "No especificada";
}
// Constructor con argumentos
public Persona(String nombre, int edad, String ocupacion) {
this.nombre = nombre;
this.edad = edad;
this.ocupacion = ocupacion;
}
public void presentarse() {
System.out.println("Soy " + nombre + ", tengo " + edad + " años y trabajo como " + ocupacion);
}
}
Si no se define un constructor, Java proporciona uno predeterminado sin argumentos. Los constructores pueden sobrecargarse para ofrecer diferentes formas de inicialización. También pueden llamar a otros constructores usando this() como primera instrucción.
Encapsulamiento
El encapsulamiento es uno de los pilares de la POO. Oculta los detalles internos de un objeto y expone solo una interfaz pública para interactuar con él.
Modificadores de Acceso
Java ofrece modificadores como public, private, protected y por defecto (paquete) para controlar la visibilidad de los miembros de una clase.
Paquetes para Organización
Los paquetes agrupan clases relacionadas, evitando conflictos de nombres. Se importan con la instrucción import, por ejemplo: import java.util.ArrayList;.
Miembros Estáticos
Las variables y métodos estáticos pertenecen a la clase en lugar de a instancias específicas. Se accede a ellos directamente a través de la clase.
public class Contador {
// Variable estática: compartida por todas las instancias
private static int totalInstancias = 0;
public Contador() {
totalInstancias++;
}
// Método estático
public static int obtenerTotalInstancias() {
return totalInstancias;
}
}
Los métodos estáticos no pueden acceder directamente a miembros no estáticos porque no tienen referencia this.
Bloques de Código
Los bloques de código son secciones delimitadas por llaves. En Java, existen bloques estáticos y de instancia para inicialización.
Bloques de Inicialización
Los bloques de instancia se ejecutan antes del constructor y se usan para inicializar variables de instancia. Los bloques estáticos se ejecutan una vez al cargar la clase.
public class Inicializador {
private static int valorEstatico;
private int valorInstancia;
// Bloque estático
static {
valorEstatico = 100;
System.out.println("Bloque estático ejecutado");
}
// Bloque de instancia
{
valorInstancia = 50;
System.out.println("Bloque de instancia ejecutado");
}
public Inicializador() {
System.out.println("Constructor ejecutado");
}
}
Representación de Objetos con toString
Al imprimir un objeto directamente, se muestra su dirección de memoria. Para una representación personalizada, se sobrescribe el método toString.
public class Empleado {
private String nombre;
private int id;
public Empleado(String nombre, int id) {
this.nombre = nombre;
this.id = id;
}
@Override
public String toString() {
return "Empleado [nombre=" + nombre + ", id=" + id + "]";
}
public static void main(String[] args) {
Empleado emp = new Empleado("Ana", 101);
System.out.println(emp); // Salida: Empleado [nombre=Ana, id=101]
}
}