Semana 2

  • Introducción a la sintaxis de Java
  • Diferencias clave con Python
  • Conceptos básicos de orientación a objetos

Características de la Orientación a Objetos

1. Todo es parte de un objeto: Los datos y comportamientos están unidos 2. Organización del Código: Cada objeto maneja sus propios datos 3. Reutilización: Podemos crear objetos similares fácilmente 4. Claridad: El código refleja el mundo real

Características Fundamentales de POO

La Programación Orientada a Objetos se basa en cuatro características principales:

  1. Encapsulación: Ocultar los detalles internos
  2. Abstracción: Modelar objetos del mundo real
  3. Herencia: Reutilizar y extender código
  4. Polimorfismo: Múltiples formas de comportamiento

Encapsulación

¿Qué es?

  • Ocultar los detalles internos de un objeto para simplificar el uso
  • Proteger los datos del acceso directo y evitar inconsistencias
  • Agregar lógica de negocio transparente. setEdad() no debería aceptar negativos

En Java se implementa con:

  • Modificadores de acceso: public, private, protected
  • Métodos getters y setters
class CuentaBancaria {
    private double saldo;  // Solo accesible dentro de la clase
    
    public void depositar(double monto) {
        if (monto > 0) {
            saldo += monto;
        }
    }
}

Abstracción

¿Qué es?

  • Modelar objetos complejos de forma simplificada
  • Enfocarse en lo importante, ignorar lo no esencial

En Java se implementa con:

  • Clases abstractas (abstract class)
  • Interfaces (interface)
interface Vehiculo {
    void mover();  // Qué hace, no cómo lo hace
}

class Coche implements Vehiculo {
    public void mover() {
        // Implementación específica
    }
}

Herencia

¿Qué es?

  • Crear nuevas clases basadas en existentes
  • Compartir código entre clases similares

En Java se implementa con:

  • Palabra clave extends
  • Herencia simple (una sola clase padre)
class Animal {
    void comer() {
        // Implementación
    }
}

class Perro extends Animal {
    void ladrar() {
        // Implementación específica
    }
}

Polimorfismo

¿Qué es?

  • Diferentes comportamientos para una misma acción
  • Tratar objetos diferentes de manera uniforme

En Java se implementa con:

  1. Sobrescritura (Override) - Polimorfismo de subtipo:

    • Redefinir métodos de la clase padre
    • Usar @Override
    • Ocurre en tiempo de ejecución
  2. Sobrecarga (Overload) - Polimorfismo ad-hoc:

    • Múltiples versiones del mismo método
    • Diferentes parámetros
    • Ocurre cuando creamos clases
class Animal {
    void hacerSonido() {
        // Implementación base
    }
}

class Perro extends Animal {
    // Sobrescritura: mismo método, diferente implementación
    @Override
    void hacerSonido() {
        System.out.println("Guau");
    }
    
    // Sobrecarga: mismo nombre, diferentes parámetros
    void hacerSonido(int veces) {
        for(int i = 0; i < veces; i++) {
            hacerSonido();
        }
    }
    
    void hacerSonido(String intensidad) {
        if(intensidad.equals("fuerte")) {
            System.out.println("GUAU!");
        } else {
            System.out.println("guau...");
        }
    }
}

Clase vs Objeto

Clase:

  • Es el plano o plantilla (los planos en papel)
  • Define atributos y comportamientos
  • Es un concepto abstracto
  • Se define una vez

Objeto:

  • Es una instancia de una clase (la casa)
  • Tiene valores específicos
  • Es concreto y existe en memoria
  • Se pueden crear muchos
// Definición de una clase
class Coche {
    String marca;
    String modelo;
    
    void arrancar() {
        System.out.println("El coche arranca");
    }
}

// Creación de objetos
Coche coche1 = new Coche();  // Primer objeto
coche1.marca = "Toyota";
coche1.modelo = "Corolla";

Coche coche2 = new Coche();  // Segundo objeto
coche2.marca = "Honda";
coche2.modelo = "Civic";

Tipos de Datos en Java vs Python

Python: Tipado dinámico, todo es un objeto Java: Tipado estático, diferencia entre primitivos y objetos

Primitivos en Java:

int numero = 42;        // Similar a Python pero debe declararse
boolean verdad = true;  // En Python es True
char caracter = 'a';    // En Python no existe char

Tipos Primitivos vs Clases Envolturas

Primitivos: byte, short, int, long, float, double, boolean, char Clases Envolturas: Byte, Short, Integer, Long, Float, Double, Boolean, Character Son útiles cuando usamos colecciones

// Primitivo
int numero = 42;

// Clase envoltura
Integer numeroObjeto = Integer.valueOf(42);
// Permite null
Integer nulo = null; // Válido
int primitivo = null; // ¡Error!

Collections en Java

ArrayList: Lista dinámica de elementos

  • Permite elementos duplicados
  • Mantiene el orden de inserción
  • Acceso rápido por índice (como arrays)
  • Puede crecer dinámicamente
  • Ideal para: listas ordenadas, acceso frecuente por posición
  • Limitación: búsquedas lentas (debe recorrer elementos)
ArrayList<String> nombres = new ArrayList<>();
nombres.add("Ana");     // ["Ana"]
nombres.add("Ana");     // ["Ana", "Ana"] - permite duplicados
nombres.get(0);         // "Ana" - acceso por índice

HashSet en Java

HashSet: Colección de elementos únicos

  • No permite duplicados
  • No mantiene orden de inserción
  • Búsqueda muy rápida
  • Ideal para: eliminar duplicados, verificar existencia de elementos
  • Limitación: no hay acceso por índice, no mantiene orden
HashSet<String> nombres = new HashSet<>();
nombres.add("Ana");     // ["Ana"]
nombres.add("Ana");     // ["Ana"] - ignora duplicados
nombres.contains("Ana"); // true - búsqueda rápida

Estructuras de Control: Diferencias con Python

For Loops

En Python:

for i in range(5):
    print(i)

for nombre in nombres:
    print(nombre)

En Java:

// Con índice
for (int i = 0; i < 5; i++) {
    System.out.println(i);
}

// For-each (como en Python)
for (String nombre : nombres) {
    System.out.println(nombre);
}

While y Do-While

While (existe en ambos):

while (condicion) {
    // código
}

Do-While (exclusivo de Java):

do {
    // Se ejecuta al menos una vez
} while (condicion);

Switch en Java (No existe en Python)

String dia = "Lunes";
switch (dia) {
    case "Lunes":
        System.out.println("Primer día");
        break;
    case "Martes":
        System.out.println("Segundo día");
        break;
    default:
        System.out.println("Otro día");
}

Enumeraciones (No existen en Python)

enum DiaSemana {
    LUNES, MARTES, MIERCOLES, JUEVES, VIERNES, SABADO, DOMINGO
}

DiaSemana hoy = DiaSemana.LUNES;

Strings en Java

Los Strings son inmutables - cada operación crea un nuevo String:

String nombre = "Juan";
String nombreMayusculas = nombre.toUpperCase(); // Nuevo String
System.out.println(nombre);           // "Juan"
System.out.println(nombreMayusculas); // "JUAN"

// Concatenación crea nuevos objetos
String completo = nombre + " Pérez";  // Nuevo String

Métodos de String

Cada método retorna un nuevo String:

String texto = "Hola Mundo";

String mayusculas = texto.toUpperCase();    // "HOLA MUNDO"
String subcadena = texto.substring(0, 4);   // "Hola"
String[] palabras = texto.split(" ");       // ["Hola", "Mundo"]
boolean contiene = texto.contains("Mundo"); // true
int longitud = texto.length();             // 10

// El String original no cambia
System.out.println(texto); // "Hola Mundo"

Igualdad entre Objetos (Introducción)

  • Para objetos, el operador == evalúa igualdad en referencias en memoria, no contenido
  • En datos primitivos, el operador == sí funciona como intuitivamente pensaríamos que funciona
String str1 = "Hola";
String str2 = "Hola";
String str3 = new String("Hola");

// NO hacer esto - comportamiento no confiable
System.out.println(str1 == str2);      // ¡No comparar Strings con ==!

// Forma correcta de comparar Strings
System.out.println(str1.equals(str2));  // true
System.out.println(str1.equals(str3));  // true

Ejercicio Práctico: Sistema de Biblioteca

Crear un sistema simple que demuestre los conceptos vistos:

  1. Usar enum para el estado del libro (DISPONIBLE, PRESTADO)
  2. Usar ArrayList para gestionar una colección de libros
  3. Mantener los datos organizados en una clase
// Estados posibles de un libro
enum EstadoLibro {
    DISPONIBLE, PRESTADO
}

// Clase para representar un libro
class Libro {
    String titulo;
    String autor;
    EstadoLibro estado;

    Libro(String titulo, String autor) {
        this.titulo = titulo;
        this.autor = autor;
        this.estado = EstadoLibro.DISPONIBLE;
    }
}

// Clase para gestionar la biblioteca
class Biblioteca {
    ArrayList<Libro> libros;

    Biblioteca() {
        libros = new ArrayList<>();
    }

    void agregarLibro(Libro libro) {
        libros.add(libro);
    }

    void prestarLibro(Libro libro) {
        libro.estado = EstadoLibro.PRESTADO;
    }
}

Uso del Sistema de Biblioteca

public class Main {
    public static void main(String[] args) {
        // Crear una biblioteca
        Biblioteca biblioteca = new Biblioteca();
        
        // Crear algunos libros
        Libro libro1 = new Libro("Don Quijote", "Cervantes");
        Libro libro2 = new Libro("Cien años de soledad", "García Márquez");
        
        // Agregar libros a la biblioteca
        biblioteca.agregarLibro(libro1);
        biblioteca.agregarLibro(libro2);
        
        // Prestar un libro
        biblioteca.prestarLibro(libro1);
    }
}