Programación Orientada a Objetos (POO)#

La Programación Orientada a Objetos (POO) es un paradigma de programación que utiliza «objetos» para modelar datos y comportamientos del mundo real. Cada objeto es una instancia de una «clase», que define las propiedades (atributos) y las acciones (métodos) que el objeto puede realizar.

  • Concepto:
    En POO, el software se diseña y organiza en torno a «objetos», que pueden ser físicos o conceptuales. Este enfoque es diferente al paradigma de programación estructurada, donde el enfoque principal son las funciones o procedimientos.

  • Metodología:
    La POO se basa en cuatro pilares fundamentales:

    • Herencia: Permite que una clase (subclase) herede atributos y métodos de otra clase (superclase).

    • Polimorfismo: Habilidad de los objetos de diferentes clases para responder al mismo mensaje o método de formas distintas.

    • Abstracción: Proceso de ocultar detalles complejos y mostrar solo los esenciales.

    • Encapsulamiento: Agrupar datos y métodos que operan sobre esos datos en una sola unidad (clase) y protegerlos del acceso externo.

https://lh6.googleusercontent.com/yPsibbUh1aHOvi0U3-wtdlNpWWutbyYULv1PLkx0QlOOq81DiXVvPgvKVrtY7Ef1yZF5NLabXrHBjHL80lx9hTqR_64jGRFZdbR9FIs4LDR9RcEn1M9LX_D5i4fYKR4vNZA-dZ9R

Figura 3 Conceptos básicos de la programación orientada a objetos (POO). Imagen tomada de Why Object-Oriented Programming Matters.#

Atributos, Métodos y Visibilidad#

  • Atributos:
    Los atributos son las variables que pertenecen a una clase. Representan las propiedades o características del objeto. En Java, los atributos suelen declararse como variables de instancia.

public class Persona {
    public String nombre;
    private int edad;

    // Agrega tres atributos de diferente tipo (float, char, etc)
}

// Define la clase con tu nombre e imprime los atributos, ¿se pueden imprimir todos?


// Da un valor a los atributos e imprimelos
  • Métodos:
    Los métodos son funciones que pertenecen a una clase y definen el comportamiento de los objetos. Los métodos pueden acceder y modificar los atributos de la clase.

public class Persona {
    private String nombre;
    private int edad;

    public void setNombre(String nombre) {
        this.nombre = nombre;
    }

    public String getNombre() {
        return nombre;
    }

    // Agrega un método que imprima el nombre y la edad

}

// Crea el objeto con tu nombre y prueba los tres métodos
  • Visibilidad:
    La visibilidad define quién puede acceder a los atributos y métodos de una clase. En Java, se usan los modificadores de acceso:

    • private: Solo accesible dentro de la misma clase.

    • protected: Accesible dentro de la misma clase, subclases y el mismo paquete.

    • public: Accesible desde cualquier parte del programa.

    • default (sin modificador): Accesible dentro del mismo paquete.

public class Persona {
    private String nombre; // Atributo privado
    public void setNombre(String nombre) { // Método público
        this.nombre = nombre;
    }
    // Agrega otro método que retorne el nombre

}

// Define un objeto de la clase Persona y ejecuta el método setNombre, ¡hace falta algo?

Clases#

Una clase es una plantilla o un modelo que define un conjunto de atributos y métodos comunes a todos los objetos que pertenecen a esa clase. En esencia, una clase describe las propiedades y comportamientos que sus objetos asociados tendrán. Es la definición abstracta del concepto que se desea modelar.

public class Persona {
    private String nombre;
    private int edad;
    // Agrega 3 atributos más de diferente tipo de variable

    // Constructor
    public Persona(String nombre, int edad) {
        this.nombre = nombre;
        this.edad = edad;
        // Modifica el constructor y agrega los tres atributos que se definieron anteriormente
    }

    // Métodos
    public void mostrarInformacion() {
        System.out.println("Nombre: " + nombre + ", Edad: " + edad);
        // Modifica este método y agrega los atributos que agregaste
    }
}

// Crea un objeto de la clase Persona y prueba el constructor

// Llama el método que muestra toda la información de la persona

En este ejemplo, Persona es una clase que define dos atributos (nombre y edad) y un método (mostrarInformacion). Esta clase es una abstracción de lo que significa ser una persona en el contexto del programa.

Objetos#

Un objeto es una instancia de una clase. Cuando se crea un objeto, se reserva memoria para almacenar sus atributos, y el objeto puede utilizar los métodos definidos en su clase. Cada objeto tiene su propio estado independiente, determinado por los valores de sus atributos.

En este fragmento de código, persona1 y persona2 son objetos de la clase Persona. Cada objeto tiene su propio conjunto de atributos (nombre y edad), lo que permite que se almacene y maneje información distinta para cada persona.

Metodología de la POO#

La POO se estructura en torno a cuatro pilares fundamentales: Encapsulamiento, Abstracción, Herencia, y Polimorfismo.

https://miro.medium.com/v2/resize:fit:720/format:webp/0*GQCVlaNMkJQXWF8C.png

Figura 4 Los 4 pilares de la POO. Imagen tomada de What is OOP (Object Oriented Programming)?.#

A continuación, se describe cada pilar acompañado de ejemplos en Java.

Encapsulamiento#

El encapsulamiento es la práctica de agrupar datos (atributos) y comportamientos (métodos) en una sola unidad llamada clase, y restringir el acceso a ciertos detalles de implementación desde el exterior. Esto se logra mediante modificadores de acceso como private, protected, y public.

public class CuentaBancaria {
  private double saldo;

  public CuentaBancaria(double saldoInicial) {
      this.saldo = saldoInicial;
  }

  public void depositar(double cantidad) {
      if (cantidad > 0) {
          saldo += cantidad;
      }
  }

  public void retirar(double cantidad) {
      if (cantidad > 0 && cantidad <= saldo) {
          saldo -= cantidad;
      }
  }

  public double getSaldo() {
      return saldo;
  }
}

// Crea un objeto de la clase CuentaBancaria y prueba sus atributos y métodos.
// Si es necesario agrega más código a la clase

En este ejemplo, el atributo saldo está encapsulado dentro de la clase CuentaBancaria, lo que impide que sea modificado directamente desde fuera de la clase. Los métodos depositar, retirar, y getSaldo proporcionan una interfaz controlada para interactuar con el saldo.

Herencia#

La herencia permite crear una nueva clase basada en una clase existente. La nueva clase (subclase) hereda atributos y métodos de la clase existente (superclase), lo que facilita la reutilización de código y la creación de jerarquías.

public class Persona {
    private String nombre;
    private int edad;

    public Persona(String nombre, int edad) {
        this.nombre = nombre;
        this.edad = edad;
        // Agrega 2 atributos más y modifica el constructor

    }

    public void mostrarInformacion() {
        // Actualiza el código para que muestre todos los atributos
        System.out.println("Nombre: " + nombre + ", Edad: " + edad);
    }
}

public class Estudiante extends Persona {
    private String carrera;

    public Estudiante(String nombre, int edad, String carrera) {
        super(nombre, edad);
        this.carrera = carrera;
        // Agrega 2 atributos más y modifica el constructor

    }

    public void mostrarInformacion() {
        // Actualiza el código para que muestre todos los atributos
        super.mostrarInformacion();
        System.out.println("Carrera: " + carrera);
    }
}

// Crea un objeto de la clase Estudiante y pasale los datos necesarios.

// Ejecuta el método que muestra toda su información

En este ejemplo, la clase Estudiante hereda los atributos nombre y edad de la clase Persona y añade el atributo carrera. Además, sobrescribe el método mostrarInformacion() para añadir información adicional sobre la carrera del estudiante.

Polimorfismo#

El polimorfismo permite que objetos de diferentes clases sean tratados como objetos de una clase común, generalmente a través de una referencia de la superclase o una interfaz. Esto significa que un mismo método puede comportarse de diferentes maneras según el objeto que lo invoque.

class Animal {
    public void hacerSonido() {
        System.out.println("El animal hace un sonido");
    }
}

class Perro extends Animal {
    @Override
    public void hacerSonido() {
        System.out.println("Guauuuu");
    }
}

class Gato extends Animal {
    @Override
    public void hacerSonido() {
        System.out.println("Miauuu");
    }
}

// Crea otra clase de tu animal favorito que extienda la clase Animal

public class TestPolimorfismo {
    public static void main(String[] args) {
        Animal miAnimal = new Animal();
        Animal miPerro = new Perro();
        Animal miGato = new Gato();
        // Define el objeto que agregaste


        miAnimal.hacerSonido(); // El animal hace un sonido
        miPerro.hacerSonido();  // El perro ladra
        miGato.hacerSonido();   // El gato maúlla
        // Prueba el sonido de tu animal

    }
}

// Crea un objeto de la clase TestPolimorfismo y llama el método main

En este ejemplo, Perro y Gato son subclases de Animal, y ambas sobrescriben el método hacerSonido(). Gracias al polimorfismo, la referencia de tipo Animal puede apuntar a objetos de tipo Perro o Gato, y el método hacerSonido() se ejecuta de acuerdo con el tipo real del objeto.

Abstracción#

La abstracción se refiere a la capacidad de enfocarse en los aspectos esenciales de una entidad mientras se ocultan los detalles complejos. Esto permite trabajar con conceptos de alto nivel sin preocuparse por los detalles de implementación.

abstract class Figura {
    abstract double calcularArea(); // Método abstracto, sin implementación
    // Agrega un método abstracto que calcule el perímetro

}

class Circulo extends Figura {
    private double radio;

    public Circulo(double radio) {
        this.radio = radio;
    }

    @Override
    double calcularArea() {
        return Math.PI * radio * radio;
    }

    // Implementa el método que calcula el perímetro

}

class Rectangulo extends Figura {
    private double ancho;
    private double alto;

    public Rectangulo(double ancho, double alto) {
        this.ancho = ancho;
        this.alto = alto;
    }

    @Override
    double calcularArea() {
        return ancho * alto;
    }

    // Implementa el método que calcula el perímetro

}

// Implementa una clase para los triángulos que extienda la clase figura


// Prueba las tres clases y sus métodos

En este ejemplo, la clase abstracta Figura define un método abstracto calcularArea(), que debe ser implementado por cualquier subclase como Circulo y Rectangulo. Esto permite trabajar con el concepto general de una «figura» sin conocer los detalles específicos de su forma.

Ejercicios#

Taller 2

  1. Ejercicio 1: Creación de Clases y Objetos

  • Crear una clase para algo que te guste mucho (película, carros, motos, anime, música, etc) y agrega al menos 5 atributos relacionados. Implementar métodos para establecer y obtener estos valores.

  • Crear una subclase que herede de los atributos y métodos de la clase creada anteriormente. Además, añada un método que imprima un mensaje utilizando los atributos definidos.

  1. Ejercicio 2: Uso de Herencia y Polimorfismo

  • Crear la clase Licores con un al menos 5 atributos y dos métodos: uno debe ser PrecioPorPersona(NoPersonas) y otro que inventes.

  • Crear 3 clases derivadas: Pola, Rones, y otra que te guste, tales que sobrescriban los método PrecioPorPersona(NoPersonas) y el que agregaste. Implementar una clase de prueba para demostrar el polimorfismo.

Recursos Adicionales#

Guías y Tutoriales#

Videos#