#!/usr/bin/env python # -*- coding: utf-8 -*- ''' POO (OOP) prog orientada a objetos: es un paradigma de programación que proporciona medios para estructurar programas para que las propiedades y los comportamientos se agreguen en objetos individuales "Existen seres (objetos, sustantivos) que hacen cosas (comportamientos, verbos) y tienen propiedades (muchas veces adjetivos)" "Los objetos interactuan entre si enviandose mensajes (mètodos)" POO modela entidades del mundo real como objetos de software # los dunder methods o mètodos màgicos: EMPIEZAN CON DOBLE GUION BAJO __ # Ej partido de futbol: clases: futbolista, arbitro, espectador, periodista instancias de clases: son individuos de una clase EJ; Messi es una instancia de la clase Futbolista Yo soy una instancia de la clase Espectador En Python Las clases e instancias tienen atributos (adjetivos) y métodos (verbos) class Perro: # atributo de clase especie = "Canis familiaris" def __init__(self, nombre, edad, pelaje): """Método que crea una instancia""" self.nombre = nombre self.edad = edad self.pelaje = pelaje def descripcion(self): return f"{self.nombre} tiene {self.edad} años y pelo {self.pelaje}" def ladra(self, sonido): return f"{self.nombre} dijo {sonido}" # creo dos instancias de perro sultan = Perro("sultan",10,"cobrizo") firulai = Perro("firulai",5,"cafe") print(f"Objeto sultan: {sultan}") print(f"Nombre del objeto firulai: {firulai.nombre}") print(f"Pelaje de sultan: {sultan.pelaje}") # los objetos son mutables sultan.edad = 4 firulai.especie = "Raza canina" print(sultan.edad) print(firulai.especie) # describo a firulai print(firulai.descripcion()) # muestro como ladra sultan print(sultan.ladra("guau")) class Perro: # atributo de clase especie = "Canis familiaris" def __init__(self, nombre, edad, pelaje): """Método que crea una instancia""" self.nombre = nombre self.edad = edad self.pelaje = pelaje def __add__ (self1, self2): return f"{self1.nombre} y {self2.nombre} han tenido hijos" def __str__(self): return f"{self.nombre} tiene {self.edad} años y pelo {self.pelaje}" def ladra(self, sonido): return f"{self.nombre} gritó {sonido}" # sultan = Perro("sultan",10,"cobrizo") # firulai = Perro("firulai",5,"cafe") # print(firulai) # print(firulai + sultan) # HERENCIA: las clases pueden construirse a partir de otras clases # preexistentes. Las clases recien formadas se llaman hijas o secundarias # y las originales padres o principales # las clases secundarias pueden ampliar y/o borrar atributos y/o metodos # de sus padres. Las clases hijas HEREDAN los metodos y atributos de sus padres class Bulldog(Perro): # No hereda posibles modificaciones del metodo ladra en Perro # es buena idea que si las herede # def ladra(self): # return f"{self.nombre} dijo ARFF" def ladra(self): return super().ladra("ARFF") class Salchicha(Perro): def ladra(self): return f"{self.nombre} dijo guau" sultan = Bulldog("sultan",10,"cobrizo") firulai = Salchicha("firulai",5,"cafe") print(sultan) print(firulai) print(sultan.ladra()) print(firulai.ladra()) # verificamos las clases a las que pertenece sultan print(isinstance(sultan, Bulldog)) print(isinstance(sultan, Perro)) ### POLIMORFISMO sin herencia # dos clases distintas con un metodo del mismo nombre class Gato: def __init__(self,nombre): self.nombre = nombre def hablar(self): return "MIAU" class Perro: def __init__(self,nombre): self.nombre = nombre def hablar(self): return "GUAU" def habla_mascota(animal): return animal.hablar() cacho = Perro("cacho") fufu = Gato("fufu") print(f"Un perro dice {habla_mascota(cacho)}") print(f"Un gato dice {habla_mascota(fufu)}") ### POLIMORFISMO con herencia (clase abstracta animal, no se instancia) class Animal(): def hablar(self): return "MIAU" class Gato(Animal): def __init__(self,nombre): self.nombre = nombre class Perro(Animal): def __init__(self,nombre): self.nombre = nombre def hablar(self): return "GUAU" cacho = Perro("cacho") fufu = Gato("fufu") print(f"Un perro dice {cacho.hablar()}") print(f"Un gato dice {fufu.hablar()}") ''' # HERENCIA MULTIPLE: una clase hija con varios padres class Padre: def __init__(self): self.progenitor = "papá" def mensaje(self): print("Mensaje de papá") class Madre: def __init__(self): self.progenitor = "mamá" def mensaje(self): print("Mensaje de mamá") class Hijo(Padre, Madre): pass hija_maria = Hijo() print(hija_maria.progenitor) # mamá sobreescribe a papá hija_maria.mensaje()