



































Prepara tus exámenes y mejora tus resultados gracias a la gran cantidad de recursos disponibles en Docsity
Gana puntos ayudando a otros estudiantes o consíguelos activando un Plan Premium
Prepara tus exámenes
Prepara tus exámenes y mejora tus resultados gracias a la gran cantidad de recursos disponibles en Docsity
Prepara tus exámenes con los documentos que comparten otros estudiantes como tú en Docsity
Los mejores documentos en venta realizados por estudiantes que han terminado sus estudios
Estudia con lecciones y exámenes resueltos basados en los programas académicos de las mejores universidades
Responde a preguntas de exámenes reales y pon a prueba tu preparación
Consigue puntos base para descargar
Gana puntos ayudando a otros estudiantes o consíguelos activando un Plan Premium
Comunidad
Pide ayuda a la comunidad y resuelve tus dudas de estudio
Descubre las mejores universidades de tu país según los usuarios de Docsity
Ebooks gratuitos
Descarga nuestras guías gratuitas sobre técnicas de estudio, métodos para controlar la ansiedad y consejos para la tesis preparadas por los tutores de Docsity
Explicacion teorica y con ejemplo sobre programacion orientada a objetos en lenguaje python
Tipo: Guías, Proyectos, Investigaciones
1 / 43
Esta página no es visible en la vista previa
¡No te pierdas las partes importantes!
Sobrecarga de métodos Python admite lo que se llama sobrecarga de métodos: puede haber varios métodos con el mismo nombre, pero a los cuales se les pasan distintos parámetros. Según los parámetros que se le pasen, se invocará al método con los valores por defecto especificados. Por ejemplo, las funciones saluda y add están sobrecargadas y permiten la entrada de diferentes parámetros en número (saluda) y en tipos de datos para que haga diferentes operaciones (add). La función saluda implementa un polimorfismo por sobrecarga de funciones. La función saluda puede recibir 0, 1 o 2 parámetros, es decir, existen 4 funciones saluda diferentes y se puede realizar mediante la indicación de valores por defecto en los parámetros de la función. Esto hace que esos parámetros sean opcionales. La función add implementa un polimorfismo de coerción, ya que una misma operación (suma) puede producir diferentes resultados dependiendo del tipo de operandos (sumar si los parámetros son enteros o concatenar si los parámetros son strings). El polimorfismo por sustitución lo estudiaremos más adelante, en la sección 1.3. En Python, al tener un tipado dinámico y utilizar el duck typing, no es necesario ni posible implementar el polimorfismo parámetrico utilizando genéricos.
Constructores (init) Constructores son métodos cuyo nombre es siempre init(self, [PARAM_OPCIONALES]) y que nunca devuelven ningún tipo de dato. Los constructores se emplean para inicializar los valores de los objetos y realizar las operaciones que sean necesarias para la generación de este objeto (crear otros objetos que puedan estar contenidos dentro de este objeto, abrir un archivo o una conexión de internet.....). Los constructores se comportan como cualquier otro método con estas dos peculiaridades: el nombre debe ser init y no pueden devolver ningún tipo de dato. Como cualquier método, un constructor admite sobrecarga. Cuando creamos un objeto (ya se verá más adelante como se hace) podemos invocar al constructor que más nos convenga.
Modificadores de variables public: Pública, puede acceder todo el mundo a esa variable. protected: Protegida, sólo pueden acceder a ella las clases hijas de la clase que posee la variable y las que estén en el mismo package. Se definen mediante _ al inicio de su definición. private: Privada, nadie salvo la clase misma puede acceder a estas variables. Se definen mediante __ al inicio de su definición. static: Estática, esta variable es la misma para todas las instancias de una clase, todas comparten ese dato. Si una instancia lo modifica todas comparten y ven dicha modificación. También se les llama variables de clase. Estas variables se definen fuera de cualquier método de la clase. Estos métodos deben llamarse siempre con el nombre de la clase y el nombre del atributo. Por ejemplo, para acceder a la variable estática de la clase animal, se haría mediante Animal.numAnimales
Modificadores de un método public: Público, puede acceder todo el mundo a este método. protected: Protegido, sólo pueden acceder a él las clases hijas de la clase que posea el método y las que estén en el mismo package. Se inicializa con un guion bajo _nombreMetodo private: Privada, nadie salvo la clase misma puede acceder a estos métodos. Se inicializa con dos guiones bajos __nombreMetodo static: Estática, es un método al cual se puede invocar sin crear ningún objeto de dicha clase. Math.sin, Math.cos son dos ejemplos de métodos estáticos. Desde un método estático sólo podemos invocar otros métodos que también sean estáticos. Se especifican con la etiqueta @staticmethod A continuación mostramos un ejemplo de una clase que define métodos estáticos. Estos métodos se podrían invocar, por ejemplo, como Mat.cuadrado (4). En este caso, como son métodos estáticos (se instancian desde la clase), no hace falta que reciban el propio objeto que les llama ¡no hay self!). Es decir, podemos asumir que en Python todos aquellos atributos referentes a la instancia (diferentes objetos) deben llevar el self delante y deben estar definidas dentro de algún método, mientras que las variables de clase no llevan el self y están definidas en la clase fuera de cualquier método. En cuanto a los métodos, los métodos estáticos deben llevar siempre la etiqueta @staticmethod.
Otro ejemplo de un método estático con la clase Animal puede ser obtener el número de animales que tenemos. NumAnimales está definida fuera de cualquier función y no lleva el prefijo self. Age, name and vivo sí están definidas y accedidas en los diferentes métodos.
Este sería un ejemplo de código que usase esta clase:
En los ejemplos Vector2D y Vector se pueden ver explicaciones en los comentarios sobre cómo la herencia facilita la resolución del problema aplicando la herencia.
Cuando en Python indicamos que una clase extiende (o hereda de) otra clase estamos indicando que es una clase hija de esta y que, por lo tanto, hereda todos sus métodos y variables. Este es un poderoso mecanismo para la reusabilidad del código. Podemos heredar de una clase, por lo cual partimos de su estructura de variables y métodos, y luego añadir lo que necesitemos o modificar lo que no se adapte a nuestros requerimientos. Veamos un ejemplo: class Animal:
Animal.<class_attribute_name>
instances of Animal. numAnimales = 0 def init(self, age = "0", name = "Godzilla"): '''constructor of an animal :param age: age of the animal: By default -> 0 :param name: name of the animal. By Default: Godzilla :returns an instance of the Animal Class (One animal) '''
self.age = age # public attribute self.name = name # public attribute self.vivo = True Animal.numAnimales +=
:param self, our own object where it is called the method from :param other, another object ''' if other == None: return False if isinstance(other, Animal): if (self.get_name() == other.get_name()): return True return False def str(self): ''' Overwrites the str method of the animal instance They are considered equal if they have the same name :param self, our own object where it is called the method from :param other, another object ''' if(self.vivo == False): return "Soy " + self.name + " y tenia " + str(self.age) + " years cuando fallecí" else: return "Soy " + self.name + " y tengo " + str(self.age) + " years. ¡La vida pueda ser maravillosa!"
information from the class, not from the instance. @staticmethod def get_numAnimales(): return numAnimales Herencia simple Si un método no hace lo que nosotros queríamos podemos sobrescribirlo (overriding). Bastará para ello que definamos un método con el mismo nombre y argumentos. Para llamar a cualquier método de la clase Padre se puede: Utilizar la sintaxis super() y el nombre del método: super().<NOMBRE_METODO> Invocar al nombre de la clase y el nombre del método: <NOMBRE_CLASE_PADRE>.<NOMBRE_METODO> Veámoslo sobre el ejemplo anterior:
from Animal import Animal """ TODO DOC STRING OF THE MODULE IF IT CONTAINS MORE THAN ONE CLASS (NOT RECOMMENDED) """ class Perro(Animal): """ This class inheritates all attributes and methods from the Animal Class A class used to represent a Dog We only specified in the docString the attributes and methods defined in the class Perro, not in Animal! """
but it may have different parameters or attributes def init(self, age = "0", name = "Toby", pastor = True): #Llamada al método de la clase padre
Animal.init(self, age, name) #Nuevos atributos si los tuviese super() self.pastor = pastor #Nuevos getters y setters, solo para los atributos de la clase hija def set_pastor(self, pastor): self.pastor = pastor def is_pastor(self): return self.pastor #Overwritten method
def saluda(self, saludo='Guau', receptor = 'nuevo amigo'): print(saludo + " " + receptor)
@staticmethod def get_numAnimales():
Por tanto, si queremos crear una clase Terrestre, esta debe heredar de Mamíferos, que a su vez ya ha heredado de Animales, y que a su vez ya ha heredado de SerVivo. Herencia múltiple A diferencia de lenguajes como Java y C#, el lenguaje Python permite la herencia múltiple, es decir, se puede heredar de múltiples clases. La herencia múltiple es la capacidad de una subclase de heredar de múltiples súper clases. Esto conlleva un problema, y es que, si varias súper clases tienen los mismos atributos o métodos, la subclase sólo podrá heredar de una de ellas. En estos casos Python dará prioridad a las clases más a la izquierda en el momento de la declaración de la subclase. Esto puede ocurrir cuando una clase hereda de diferentes abstracciones sin relación entre sí. Para llamar a los métodos o acceder a los atributos de la clase padre, se puede utilizar la misma sintaxis que en la herencia simple, pero en este caso hay que recordar la jerarquía que sigue Python de izquierda a derecha:
Invocar a super() y el nombre del método: super().<NOMBRE_METODO>. En este caso, Python buscará el método o el atributo de izquierda a derecha según la jerarquía de herencias fue establecida. En caso de no encontrarlo en la primera, buscará en la segunda, tercera, y así sucesivamente hasta que lo encuentre. Invocar al nombre de la clase y el nombre del método: <NOMBRE_CLASE_PADRE>.<NOMBRE_METODO> Por ejemplo, si representamos todo el reino animal, y dividimos los animales por nacionalidad además de por su ontología propia, un perro español debería heredar de terrestre, puesto que es un mamífero terrestre, y de la nacionalidad filipina, puesto que es de Filipinas y compartirá sus atributos. En caso de que las clases Terrestre (o cualquier de sus clases Padre, que están contenidas en la clase hija) y Filipinas tuviesen atributos o métodos comunes, le especificamos la preferencia según el orden de izquierda a derecha. En este caso vamos a dar prioridad a la ontología de los animales respecto a la nacionalidad. from Animal import Animal from Nacionalidades import Filipinas """ TODO DOC STRING OF THE MODULE IF IT CONTAINS MORE THAN ONE CLASS (NOT RECOMMENDED) """ class Perro(Terrestre, Filipinas): Aunque la herencia múltiple es una herramienta muy potente, no va a ser objeto de estudio durante el presente curso. Si algún estudiante está interesado en su utilización, puede sentirse libre de preguntar al profesor para más información.
Aunque ya hemos visto como se crea un objeto vamos a formalizarlo un poco. Un objeto en el ordenador es esencialmente un bloque de memoria con espacio para guardar las variables de dicho objeto. Crear el objeto es sinónimo de reservar espacio para sus variables, inicializarlo es dar un valor a estas variables. Para crear un objeto se utiliza el comando new. Veámoslo sobre un ejemplo:
Con el primer comando hemos creado un puntero que apunta a una variable tipo Fecha, con los datos especificados en el constructor (29, 10, 2019) Con esta sentencia creamos una variable que se llama hoy con valor 29-10- Una vez creado un objeto será posible acceder a todas sus variables y métodos públicos, así por ejemplo en el ejemplo anterior hoy tomaría el valor 30. Si la variable fuese privada solo podrían acceder a ella sus instancias, por lo que hay que acceder a partir de sus métodos GET y SET:
De este modo no podríamos acceder a las variables de la clase Fecha, para acceder a ella tendríamos que hacerlo mediante métodos que nos devolviesen su valor. A esto se le denomina encapsulación. Esta es la forma correcta de programar OOP: no debemos dejar acceder a las variables de los objetos por otro procedimiento que no sea paso de mensajes entre métodos, esto es, a través de los GETS y SETS si no se acceden desde dentro de la clase o desde una clase hija.
Es una variable especial de sólo lectura que proporciona Python. Contiene una referencia al objeto en el que se usa dicha variable. En Pyhton es imprescindible que un objeto se refiera a sí mismo como self. Cuando necesitemos invocar a un método propio del objeto, debemos hacerlo con self. Cuando necesitemos invocar a un método estático lo haremos con el nombre de la clase Veamos dos ejemplos
Otro posible uso de this, que ya se ha visto en ejemplos anteriores es diferenciar entre variables locales o parámetros de un método o constructor y variables del objeto. En los códigos correspondientes a los ejemplos Animal.py y Perro.py el constructor de la clase Animal o Perro aunque realiza la misma función que los que se recogen en estos puntos, son ligeramente diferentes. Las variables que se llaman con self son propias del objeto desde el que se invoca, mientras las variables sin self son variables locales o parámetros.