Saltar al contenido principal
Logo FPCode

Programación orientación a objetos

Contenido

Conceptos fundamentales de la programación orientada a objetos: clases, objetos, encapsulado, relaciones y principios básicos.

Introducción

La orientación a objetos es un paradigma de programación que organiza el software en unidades llamadas objetos, los cuales contienen datos y comportamiento relacionados. Este enfoque facilita la modelización del mundo real, promoviendo la reutilización, el mantenimiento y la escalabilidad del código. En este recurso aprenderás los conceptos de la orientación a objetos, como las clases, objetos, encapsulado, relaciones entre clases y los principios básicos que sustentan este paradigma.

Conocimiento previo

Referencias

Índice

  1. Introducción a la Programación Orientada a Objetos
    1.1. ¿Por qué surge la POO?
    1.2. Principios
  2. Componentes de la POO
    2.1. Clases y objetos
    2.2. Atributos (propiedades)
    2.3. Métodos
    2.3.1. Métodos de acceso o propiedades
    2.3.2. Constructores y destructores
  3. Encapsulado y Visibilidad
  4. Relaciones entre clases
    4.1. Asociación, agregación y composición
    4.2. Herencia
    4.3. Polimorfismo
  5. Diagrama de clases
  6. Ejercicios

1. Introducción a la Programación Orientada a Objetos

La Programación Orientada a Objetos (abreviada como POO) es un paradigma de programación que cambia la forma en que pensamos y diseñamos el software.

Mientras que en la programación estructurada el foco está en las funciones y los procedimientos, en la POO el centro son los objetos, es decir, entidades que combinan datos y comportamiento en una sola unidad.

Podemos decir que la POO nos permite modelar problemas del mundo real de forma más intuitiva, representando cosas como usuarios, productos, vehículos, personajes de un videojuego o cuentas bancarias directamente en el código. Cada uno de estos elementos se convierte en un objeto, con sus propios atributos y acciones posibles.

1.1. ¿Por qué surge la POO?

Imagina un programa muy grande desarrollado únicamente con procedimiento, funciones y variables globales. 🧩 Conforme el sistema crece, se vuelve cada vez más difícil de entender, mantener y ampliar. Los cambios en una parte del código pueden afectar a otras sin que nos demos cuenta, generando errores difíciles de localizar.

En los años 70 y 80, los programadores comenzaron a buscar formas de estructurar el código de manera más modular, para poder dividir un sistema complejo en pequeñas partes independientes y reutilizables. Así es como surge la Programación Orientada a Objetos, que permite construir software basado en unidades más cercanas a cómo pensamos en la vida real: objetos con propiedades y comportamientos propios.

🗓️ Un poco de historia
El primer lenguaje que implementó conceptos orientados a objetos fue Simula 67, diseñado en los años 60 para simular entornos del mundo real. Más adelante, en los años 80, el lenguaje Smalltalk llevó la POO al siguiente nivel, y poco después se popularizaron otros como C++, Java y Python, que adoptaron estos conceptos y los hicieron accesibles a millones de programadores.

🎯 Ventajas que motivaron la aparición de la POO

  • Modularidad: Es más sencillo dividir un sistema en partes independientes.
  • Reutilización: Se pueden crear objetos y clases reutilizables en diferentes proyectos.
  • Mantenimiento más fácil: Los cambios afectan sólo a los objetos relacionados.
  • Mejor comprensión del problema: El código refleja la estructura del problema real.

💡 Ejemplo

Si piensas en un videojuego de coches, cada vehículo tiene unas propiedades que son comunes (Marca, Modelo, etc.), ahora bien sus valores cambian. Tal y como hemos aprendido ahora, necesitariamos bastantes variables para representar estas propiedades.

pseudocodigo.psc
Inicio
Definir marcaCoche1, marcaCoche2 como Cadena;
Definir velocidadMaxCoche1, velocidadMaxCoche2 como Real;
marcaCoche1 ← "Toyota";
velocidadMaxCoche1 ← 180;
marcaCoche2 ← "Renault";
velocidadMaxCoche2 ← 160;
Fin

Imagina que hay que hacer esto para 1.000 coches o que queremos incluir nuevas propiedades, como el color, modelo, etc..

Con la POO, cada coche es un objeto, y el código se organiza de una manera más natural:

pseudocodigo.psc
Inicio
Definir coche1, coche2 como Coche;
coche1 ← ("Toyota",180);
coche2 ← ("Renault",160);
Fin

De esta forma, el programa es más ordenado, más fácil de mantener y más fácil de entender.

1.2. Principios

La POO se basa en un conjunto de características fundamentales que definen su forma de trabajar.

  1. Encapsulación: proteger los datos de un objeto para que no puedan ser modificados directamente desde fuera.
  2. Abstracción: simplificar la realidad mostrando sólo lo esencial y ocultando los detalles que no son importantes para el usuario.
  3. Herencia: crear un objeto nuevo a partir de otro existente, reutilizando su código y ampliándolo.
  4. Polimorfismo: un mismo método puede comportarse de diferentes formas según el objeto que lo use.

Estos principios pueden ser dificiles de entender por primera vez. Más adelante se explicaran con mayor detalle.

2. Componentes de la POO

En la Programación Orientada a Objetos, el código se organiza a través de componentes principales que permiten construir y estructurar los programas.

Estos componentes son los bloques básicos con los que se modelan las entidades del mundo real dentro del software.

2.1. Clases y objetos

¿Qué es una clase?

Una clase es como un molde o una plantilla que define cómo serán los objetos que se creen a partir de ella.

Dentro de una clase se describen:

  • Los atributos (también llamados propiedades), que representan las características o datos del objeto.
  • Los métodos, que son las acciones o comportamientos que ese objeto puede realizar.

Siguiendo el ejemplo del coche 🚗:

Imagina que quieres modelar un coche en un programa. La clase Coche podría tener:

  • Atributos: marca, modelo, color, velocidad.
  • Métodos: acelerar(), frenar(), girar().
¿Qué es un objeto?

Un objeto es una instancia concreta de una clase. Es decir, cuando creas un objeto, estás creando un ejemplar real de esa clase.

Ejemplo:

Si tienes la clase Coche, puedes crear varios objetos:

  • miCoche → marca: Toyota, modelo: Corolla
  • tuCoche → marca: Ford, modelo: Focus

Cada objeto tiene sus propios datos, aunque comparten la misma estructura y comportamientos definidos en la clase.

2.2. Atributos (propiedades)

Los atributos o propiedades son las características o datos que describen a un objeto dentro de una clase.
Son las variables que guardan información sobre el estado particular de cada objeto.

Ya habiamos indicado en el anterior apartado que en un Coche sus atributos podrían ser:

  • marca
  • modelo
  • color
  • velocidad

Cada objeto creado a partir de la clase tendrá sus propios valores para estos atributos.

pseudocodigo.psc
Inicio
Clase Coche:
atributo marca
atributo modelo
atributo color
atributo velocidad
miCoche = Coche()
miCoche.marca = "Toyota"
miCoche.modelo = "Corolla"
miCoche.color = "Rojo"
miCoche.velocidad = 0
Fin

Estado de los objetos
Los atributos representan el estado del objeto en un momento dado. Si cambias los valores de los atributos, estás modificando el estado del objeto.

Por ejemplo, si aceleras el coche, el atributo velocidad cambia:

pseudocodigo.psc
Inicio
miCoche.velocidad = 50
Fin

2.3. Métodos

Los metodos materializan las acciones que van a tener los objetos, es decir, es la forma en que se implementa un algoritmo que se aplica a todas las instancias de una clase, y si se desea, pueden utilizar los datos de los atributos que contiene cada objeto.

Un método puede comportarse como:

  • Función. Cuando el algoritmo que contiene, al ser llamado, realiza una serie de instrucciones y por último devuelve un valor.
  • Procedimiento. Cuando el algoritmo que contiene, al ser llamado, lleva a cabo una serie de acciones, pero en el resultado final no se espera que devuelva ningún valor.

Varios son los factores de los que depende que un método se implemente como procedimiento o como función. Primero, depende del lenguaje de programación utilizado, ya que algunos como Java solo utilizan funciones (no existen procedimientos como tal), y otros como Delphi distinguen entre funciones y procedimientos.

Los métodos pueden recibir parámetros o argumentos, que permiten enviar datos al algoritmo para que pueda realizar su funcionalidad. Estos parámetros se comportan como variables que solo sirven dentro del bloque del método.

Los parámetros o argumentos puede ser enviados al método de dos formas:

  • Por valor -> Se crea una copia exacta de la información, una vez utilizada por el método, los datos del parámetro no se verán alterados.
  • Por referencia -> Se envia una dirección de memoria dónde se encuentran los datos del parámetro, cuando se utiliza dentro del método los datos se verán afectados una vez finalizado.

2.3.1. Métodos de acceso o propiedades

2.3.1. Constructores y destructores

Existen unos métodos especiales que tienen un comportamiento extra a un método normal. Existen los constructores y destructores, aún que es posible que dependiendo del lenguaje, existan estos métodos o no.

Constructores Este método pertenece a una clase concreta y permite instanciar objetos que pertenecen a esta. Es decir, es el encargado de “crear” los objetos a partir de la clase.

Cada clase puede contar con varios métodos constructores definidos dependiendo de la cantidad de parametros que reciba, aunque también puede suceder el caso de que no se defina ninguno. Que no se defina un método constructor, no significa que no exista; todas las clases cuentan por defecto con un método constructor que, al llamarse, inicializará a los valores por defecto los campos de dicha clase.

Los métodos constructores se podrán identificar facilmente porque utilizan por defecto el mismo nombre de la clase.

public Coche() {
}

Destructores Es lo contrario al constructor, estos métodos permiten “destruir” cualquier objeto creado previamente. Gracias a esto, se puede liberar aquellos recursos que el objeto tuviera asignado.

En lenguajes de programación más modernos ya casi no se utilizá los destructores, ya que utilizan herramientas y mecanismos automáticos para realizar estas funciones. En los lenguajes de programación que no existan automatismos para destruir objetos, serán los programadores los responsables que deben utilizar los destructores en los momentos adecuados.

🔐 Visibilidad y encapsulamiento de atributos

Por buenas prácticas, los atributos suelen ser privados o protegidos para que no puedan modificarse directamente desde fuera del objeto.
En cambio, se usan métodos públicos para acceder y modificar estos atributos, garantizando un mejor control (esto forma parte del encapsulamiento).

La visibilidad determina la manera en que los miembros de una clase son accedidos desde otros puntos del programa. Es importante no solo para crear relaciones de herencia entre distintas clases, sino también para implementar los algoritmos. La visibilidad se puede aplicar a nivel de los atributos, métodos, clases y la forma de estructurar el programa, en paquetes y librerías. Distinguimos entre los siguientes tipos de visibilidad: • Privada: representada con el signo menos (-). Los miembros declarados con este tipo de visibilidad solo podrán verse desde la misma clase desde la que se declararon. • Pública: representada con el signo de suma (+). Estos miembros podrán verse desde cualquier parte del programa. • Protegida: representada con el signo de almohadilla (#). Estos miembros se verán solo desde la clase desde la que se declararon y aquellas clases que hereden de esta.

Existen tipos de lenguaje de programación que cuentan con algún tipo de visibilidad adicional.

2.3. Diagrama de clases

Un diagrama de clase es un tipo de diagrama en el Lenguaje de Modelado Unificado (UML) que representa la estructura y el comportamiento de un sistema o programa.

Se utiliza para visualizar las diferentes clases u objetos en un sistema, junto con sus atributos, métodos y relaciones entre sí.

Los diagramas de clase se utilizan comúnmente durante las fases de diseño e implementación del desarrollo de software para ayudar a los desarrolladores y las partes interesadas a comprender la estructura y el comportamiento del sistema que se está desarrollando.