Programación orientada a objetos

¿Te gustaría entender cómo piensan los lenguajes modernos como Java, Python o C#? En este artículo vas a descubrir los principios de la Programación Orientada a Objetos (POO), un paradigma clave para escribir código más organizado, reutilizable y escalable. Aprendé desde los conceptos fundamentales como clases, objetos, herencia y polimorfismo, hasta buenas prácticas de diseño y diagramas UML.

Fecha de publicación: Mayo 15, 2025

Última actualización: Mayo 15, 2025

Programación orientada a objetos

📌 Introducción

La Programación Orientada a Objetos (POO) es un paradigma de programación basado en el uso de objetos, que combinan datos (atributos) y comportamientos (métodos) en una sola entidad. Estos objetos son instancias de clases, que actúan como moldes o plantillas. La POO permite modelar sistemas complejos de forma más natural, dividiendo el problema en pequeñas unidades interconectadas.

La POO es ampliamente utilizada porque:

Diferencias entre POO y programación estructurada

CaracterísticaProgramación estructuradaProgramación orientada a objetos
Estructura principalFunciones y procedimientosClases y objetos
EnfoqueFlujo de control secuencialInteracción entre objetos
Organización del códigoAgrupación por funcionesAgrupación por entidad (objeto)
Reutilización de códigoDifícil de mantenerMás simple con herencia
MantenimientoPropenso a errores al crecerEscalable y modular



🧱 Conceptos Fundamentales

Clases y Objetos

Una clase es un modelo que define las características (atributos) y comportamientos (métodos) de un conjunto de objetos. Un objeto es una instancia concreta de una clase.

class Perro:
  def __init__(self, nombre, edad):
    self.nombre = nombre
    self.edad = edad

  def ladrar(self):
    print(f"{self.nombre} dice: ¡Guau!")

Atributos y Métodos

Los atributos son variables que almacenan el estado de un objeto, mientras que los métodos son funciones que definen el comportamiento del objeto.

En el ejemplo anterior, nombre y edad son atributos, y ladrar es un método.

Encapsulamiento

El encapsulamiento es el principio de ocultar los detalles internos de un objeto y exponer solo lo necesario. Esto se logra mediante modificadores de acceso (público, privado, protegido).

class Perro:
  def __init__(self, nombre, edad):
    self.nombre = nombre
    self.edad = edad

  def ladrar(self):
    print(f"{self.nombre} dice: ¡Guau!")

  def obtener_edad(self):
    return self.edad

  def establecer_edad(self, nueva_edad):
    if nueva_edad > 0:
        self.edad = nueva_edad
    else:
        print("La edad debe ser positiva.")

En este ejemplo, obtener_edad y establecer_edad son métodos públicos que permiten acceder y modificar el atributo edad, mientras que el atributo nombre es privado y no puede ser accedido directamente desde fuera de la clase.

Abstracción

La abstracción es el proceso de simplificar un objeto al enfocarse en sus características esenciales y ocultar los detalles innecesarios. Esto se logra mediante la creación de clases abstractas e interfaces.

abstract class Animal {
  abstract void hacerSonido();
}

class Perro extends Animal {
  void hacerSonido() {
    System.out.println("¡Guau!");
  }
}

En este ejemplo, Animal es una clase abstracta que define un método hacerSonido, pero no lo implementa. La clase Perro hereda de Animal y proporciona su propia implementación del método.

Polimorfismo

El polimorfismo permite que diferentes clases implementen el mismo método de diferentes maneras. Esto se puede lograr mediante la sobrecarga de métodos o la implementación de interfaces.

class Gato extends Animal {
  void hacerSonido() {
    System.out.println("¡Miau!");
  }
}
class Vaca extends Animal {
  void hacerSonido() {
    System.out.println("¡Muu!");
  }
}

En este ejemplo, tanto Gato como Vaca heredan de Animal y proporcionan su propia implementación del método hacerSonido. Esto permite que el mismo método se comporte de manera diferente según el tipo de objeto que lo invoque.

Herencia

La herencia es el mecanismo que permite crear nuevas clases a partir de clases existentes, heredando sus atributos y métodos. Esto promueve la reutilización de código y la creación de jerarquías de clases.

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

class Perro extends Animal {
  void hacerSonido() {
    System.out.println("¡Guau!");
  }
}

En este ejemplo, Perro hereda de Animal, lo que significa que Perro tiene acceso a los métodos y atributos de Animal. Además, Perro puede sobrescribir el método hacerSonido para proporcionar su propia implementación.

Composición vs Herencia

La composición es un enfoque alternativo a la herencia, donde una clase contiene instancias de otras clases en lugar de heredar de ellas. Esto permite crear objetos más complejos y flexibles.

class Motor {
  void encender() {
    System.out.println("Motor encendido");
  }
}

class Coche {
  private Motor motor;

  Coche() {
    motor = new Motor();
  }

  void arrancar() {
    motor.encender();
  }
}

En este ejemplo, Coche tiene un atributo motor, que es una instancia de la clase Motor. Esto permite que Coche utilice el comportamiento de Motor sin necesidad de heredar de él. La composición es útil cuando se desea reutilizar código sin crear jerarquías complejas.

Interfaces

Una interfaz es un contrato que define un conjunto de métodos que una clase debe implementar. Las interfaces permiten la creación de código más flexible y desacoplado.

interface Volador {
  void volar();
}
class Pajaro implements Volador {
  public void volar() {
    System.out.println("El pájaro vuela");
  }
}
class Avion implements Volador {
  public void volar() {
    System.out.println("El avión vuela");
  }
}

En este ejemplo, Volador es una interfaz que define el método volar. Tanto Pajaro como Avion implementan esta interfaz, proporcionando su propia implementación del método. Esto permite que ambos objetos sean tratados de manera uniforme, a pesar de ser de tipos diferentes.



✅ Buenas Prácticas

Principios SOLID

Los principios SOLID son un conjunto de cinco principios de diseño orientado a objetos que ayudan a crear software más comprensible, flexible y mantenible:



📊 Diagramas UML

Los diagramas UML (Unified Modeling Language) son herramientas visuales que ayudan a representar y documentar el diseño de un sistema orientado a objetos. Los diagramas más comunes son: