====== Programación Orientada a Objetos ======
Paradigma de programación donde todo se modela con **objetos**.
El objetivo de la Programación Orientada a Objetos es resolver problemas a través de las interacciones entre objetos.
Un objeto es una abstracción de algún hecho o ente del mundo real, con atributos que representan sus características o propiedades, y métodos que emulan su comportamiento o actividad. Todas las propiedades y métodos comunes a los objetos se encapsulan o agrupan en clases. Una clase es una plantilla, un prototipo para crear objetos; en general, se dice que cada objeto es una instancia o ejemplar de una clase.
* [[informatica:programacion:programacion_orientada_a_objetos:php|Programación Orientada a Objetos en PHP]]
===== Pilares =====
* Encapsulamiento
* Abstracción
* Herencia
* Polimorfismo
En programación orientada a objetos veremos mucho también los conceptos siguientes:
* Acoplamiento
* Cohesión
===== Conceptos =====
* Clase: define las caractéristicas de lo que queremos modelar. Sería la plantilla/molde desde la que construir objetos.
* Objeto: ejemplares de una clase.
* Herencia
* Atributos / propiedades: características de los objetos.
* Método: funcionalidad asociada a un objeto.
* Estado: el valor concreto de una propiedad de un objeto.
* Evento
* Mensaje: acción de efectuar una llamada a un método.
==== Encapsulamiento ====
Consiste en asegurar que la información de un objeto se oculta del mundo exterior.
Al definir una clase, es importante proteger algunos métodos y propiedades para que no sean accesibles desde otras. Esto se consigue con los modificadores de acceso (//public//, //private//, //protected//).
Poner ejemplo
==== Abstracción ====
Implica que la clase debe representar las características de la entidad hacia el mundo exterior, pero ocultando la complejidad que llevan aparejada. O sea, nos abstrae de la complejidad que haya dentro dándonos una serie de atributos y comportamientos (propiedades y funciones) que podemos usar sin preocuparnos de qué pasa por dentro cuando lo hagamos.
La abstracción está muy relacionada con el encapsulamiento, pero va un paso más allá pues no sólo controla el acceso a la información, sino también oculta la complejidad de los procesos que estemos implementando.
==== Herencia ====
Cuando dos clases comparten propiedades y/o métodos, son susceptibles de convertirse en subclases y definir una súper clase con estas características comunes.
Por ejemplo, si tenemos la clase **Empleado** con las siguientes propiedades:
* Identificación
* Nombre
* Apellidos
* Edad
* Puesto
* Sueldo
* Tipo de contrato
Y la clase **Cliente** con estas propiedades:
* Identificación
* Nombre
* Apellidos
* Edad
* Código
* Categoría
Lo que podríamos hacer sería definir la súper clase **Persona** con las propiedades comunes:
* Identificación
* Nombre
* Apellidos
* Edad
Y las clases hijas:
* **Empleado**:
* Puesto
* Sueldo
* Tipo de contrato
* **Cliente**
* Código
* Categoría
Las clases hijas **heredarán** las propiedades y métodos de la clase padre y evitaremos duplicar código.
==== Polimorfismo ====
Capacidad que tienen los objetos de una clase de responder al mismo mensaje o evento.
Si tenemos una clase **Persona** con el método ''Registrarse()'' y unas clases hijas **Empleado** y **Cliente** que heredan ese método. Cada clase hija puede sobrescribir la lógica de dicho método de tal forma que cuando se use ''Registrarse()'' en un objeto de tipo **Empleado** haga una cosa y cuando se use en **Cliente** haga otra. Sin embargo, el nombre del método es el mismo. Eso es polimorfismo.
El poliformismo:
* Evita usar muchos ''if'' y ''switch'' en toma de decisiones
* Simplifica la programación
===== Objetos =====
Los objetos son entidades que tienen un determinado "estado", "comportamiento (método)" e "identidad":
* La identidad es una propiedad de un objeto que lo diferencia del resto; dicho con otras palabras, es su identificador (concepto análogo al de identificador de una variable o una constante).
* Los métodos (comportamiento) y atributos (estado) están estrechamente relacionados por la propiedad de conjunto. Esta propiedad destaca que una clase requiere de métodos para poder tratar los atributos con los que cuenta. El programador debe pensar indistintamente en ambos conceptos, sin separar ni darle mayor importancia a alguno de ellos. Hacerlo podría producir el hábito erróneo de crear clases contenedoras de información por un lado y clases con métodos que manejen a las primeras por el otro. De esta manera se estaría realizando una "programación estructurada camuflada" en un lenguaje de POO.
La programación orientada a objetos difiere de la programación estructurada tradicional en la que los datos y los procedimientos están separados y sin relación, ya que lo único que se busca es el procesamiento de unos datos de entrada para obtener otros de salida. La programación estructurada anima al programador a pensar sobre todo en términos de procedimientos o funciones, y en segundo lugar en las estructuras de datos que esos procedimientos manejan. En la programación estructurada solo se escriben funciones que procesan datos. Los programadores que emplean POO, en cambio, primero definen objetos para luego enviarles mensajes solicitándoles que realicen sus métodos por sí mismos.
===== Diagrama de clases =====
Forma gráfica de representar las clases, con sus propiedades y métodos, y las relaciones entre ellas.
Completar con ejemplos y explicaciones
===== Resumen de la Programación Orientada a Objetos =====
* La POO permite **modelar entidades** para trabajar con ellas.
* Una **clase** es una plantilla.
* Un **objeto** o **instancia** es una implementación concreta de la clase.
* **Instanciar**: crear un objeto a partird e una clase.
* Pilares de la POO:
* Encapsulamiento
* Abstracción
* Herencia
* Polimorfismo
===== Literatura recomendada =====
* [[https://www.pearson.com/us/higher-education/program/Martin-Clean-Code-A-Handbook-of-Agile-Software-Craftsmanship/PGM63937.html|Clean Code]] (Robert C. Martin; 2008; Pearsons)
* [[https://www.packtpub.com/product/python-object-oriented-programming-fourth-edition/9781801077262|Python Object-Oriented Programming]] (Steven F. Lott , Dusty Phillips; 2021; Packt)
* [[https://www.oreilly.com/library/view/head-first-object-oriented/0596008678/|Head First Object-Oriented Analysis and Design]] (Brett McLaughlin; 2006; O'Reilly)
* [[https://www.oreilly.com/library/view/head-first-design/0596007124/|Head First Design Patterns]] (Eric Freeman, Elisabeth Robson, Bert Bates, Kathy Sierra; 2004; O'Reilly)
* [[https://www.oreilly.com/library/view/the-object-oriented-thought/9780135182130/|The Object-Oriented Thought Process]] (Matt Weisfeld; 2019; O'Reilly)
* [[https://www.elegantobjects.org/|Elegant Objects]] (Yegor Bugayenko; 2016)
* [[https://www.manning.com/books/object-design-style-guide|Object Design Style Guide]] (Matthias Noback; 2019; Manning)
===== Recursos =====
* [[https://www.youtube.com/watch?v=zsw54F3aFNs|TUTORIAL: Programación Orientada a Objetos (POO): Entiéndelo BIEN por fin]]
* [[https://www.campusmvp.es/recursos/post/los-conceptos-fundamentales-sobre-programacion-orientada-objetos-explicados-de-manera-simple.aspx|Los conceptos fundamentales sobre Programación Orientada Objetos explicados de manera simple]]