Download Prácticas de Programación Orientada a Objetos

Document related concepts
no text concepts found
Transcript
Universidad
de Jaén
Departamento
de Informática
Prácticas de Programación Orientada a Objetos
Proyecto
Python vs C++
Alumnos:
Abad Vich David
Benítez Pedrero Jesús Alejandro
Grupo de Prácticas:
Profesor de Prácticas:
Fecha de entrega:
Anotaciones de corrección:
Nota:
5
Balsas Almagro, José Ramón
4 de Junio de 2012
Programación Orientada a Objetos Índice
01.Introducción ............................................................................................ 3
02.¿Qué es Python? ...................................................................................... 3
03.Definiciones previas antes de la comparación
1.Tipos de funciones miembro .................................................................................................................................. 3 2.Miembro This ......................................................................................................................................................... 4 3.Herencia ................................................................................................................................................................. 4 4.Herencias duplicadas y virtuales ............................................................................................................................ 4 5.Polimorfismo .......................................................................................................................................................... 4 6.Clases abstractas .................................................................................................................................................... 4 7.Interfaces ............................................................................................................................................................... 5 8.RTTI ........................................................................................................................................................................ 5 04.Previo a objetos ........................................................................................ 5
05.Clases en Python ..................................................................................... 6
1.¿Qué pasa si no definimos un ´constructor por defecto´? ....................................................................................... 6 2.Constructor copia ................................................................................................................................................... 7 3.Destructores ........................................................................................................................................................... 7 06.Herencia y herencia múltiple .................................................................. 7
1.Herencia de tipo virtual .......................................................................................................................................... 7 07. Polimorfismo .......................................................................................... 8
08. Módulos................................................................................................... 8
09. Instropección .......................................................................................... 8
Añadir atributos y métodos a una clase en tiempo de ejecución ................................................................................ 9 10. Excepciones ............................................................................................ 9
11. Plantillas ............................................................................................... 11
12. Métodos de la librería CSV .................................................................. 11
13. Ejemplos en Uml .................................................................................. 12
1.Python .................................................................................................................................................................. 12 2.C++ ...................................................................................................................................................................... 13 Abad Vich David y Benítez Pedrero Jesús Alejandro Página 2 Programación Orientada a Objetos Introducción
Nuestro trabajo se basa en una comparación entre Python y C++; en el cual daremos definiciones de
Python; unas breves definiciones de lo que hemos visto a lo largo del cuatrimestre en programación
orientada objetos y por último veremos ejemplos de cómo se implementan estas definiciones tanto en
Python como en C++.
Como particularidad debemos mencionar que en Python, la indexación de texto es obligatoria; ya que no
existe delimitadores de líneas de código como “;” en C++; además nos necesitamos indicarle las librerías
estándar; cosa que en C++ es obligatoria; solo debemos indicarle librerías específicas como por ejemplo:
Import csv
¿Qué es Python?
Se trata de un lenguaje de programación multiparadigma ya que soporta orientación a objetos,
programación imperativa y, en menor medida, programación funcional. Es un lenguaje interpretado, usa
tipado dinámico, es fuertemente tipado y multiplataforma.
Definición de wikipedia.
Se trata de un lenguaje de alto nivel, él cual a nuestro entender es fácil de aprender y rápido de
implementar, ya que así de fácil seria programar el “hola mundo”, (muy típico en el mundo informático)
print ("Hola mundo")
Y simplemente así sin nada más ya nos estaría saliendo por pantalla el “hola mundo”.
Además de una infinidad de ventajas como el recolector de basura; y por otro lado tenemos la “ventaja”
(según se mire) de ser un lenguaje interpretado con lo cual siempre podemos trabajar dinámicamente; lo
que nos permite por ejemplo añadir uno o varios atributos a una clase en tiempo de ejecución, cosa que
sería impensable en C++.
Definición nuestra.
Definiciones previas antes de la comparación:
•
•
•
•
•
Una CLASE describe una nuevo tipo de dato, definiendo:
o Datos que contiene.
o Funciones que operan sobre dichos datos.
Un OBJETO es cada una de las variables o instancias que se define a partir de la clase. Por ello
se dice que una clase define el conjunto de objetos del mismo tipo; pueden ser estáticos o
dinámicos (new).
A los datos almacenados por cada objeto/clase se les denomina atributos o datos miembro.
A las funciones definidas para cada objeto/clase se les denomina funciones miembro o métodos;
Las cuales pueden ser prívate, public o protected; además se puede acceder (get) o modificar
(set) el valor de dicho método.
Tipos de funciones miembro
•
•
Constructores: Permiten reservar recursos para un objeto e inicializarlos adecuadamente.
o Constructor por defecto: Crea un objeto con la inicialización básica de sus atributos.
Puede/debe sobrecargarse.
o Constructor de copia a partir de otro objeto. Debe sobrecargarse.
Destructor (~): Solo puede existir uno. Puede sobrecargarse.
o Se llama automáticamente cuando el objeto deja de existir.
Abad Vich David y Benítez Pedrero Jesús Alejandro Página 3 Programación Orientada a Objetos Miembro This
•
•
En C++ todo objeto de una clase dispone de un miembro de tipo puntero a dicho objeto.
Este miembro se puede utilizar para acceder a los miembros del propio objeto o para resolver
ambigüedades.
Herencia
•
Características
o Es transitiva: Si B hereda de A, y C de B, entonces C hereda de A.
o La subclase hereda todos los atributos y métodos de las superclases.
ƒ Se puede definir la visibilidad de los atributos y métodos heredados en la
subclase.
o La herencia es un mecanismo que facilita la reutilización de código.
ƒ Evita reescribir o copiar/pegar código de las superclases en las subclases.
ƒ Es posible definir nuevos atributos y métodos en la subclase.
ƒ Es posible redefinir los métodos de las superclases.
También existe la herencia múltiple; ejemplo de herencia múltiple y simple:
Un Vehículo de ocasión ES UN Automóvil y ES UNA Mercancía (herencia múltiple). Sin embargo la
Furgoneta del servicio técnico no es Mercancía, pero sí Automóvil (herencia simple).
Herencias duplicadas y virtuales
¾ Cuando las jerarquías con herencia múltiple aumentan su complejidad, puede ocurrir que una
clase derivada herede de una misma superclase desde varias relaciones.
¾ En este caso, la clase derivada contendrá una copia de los atributos por cada herencia de la
superclase común.
¾ Esto puede solucionarse en C++ definiendo las relaciones de herencia de tipo virtual.
Polimorfismo
Polimorfismo de objetos: en relaciones de herencia, un objeto puede comportarse como elemento de
cualquiera de las clases de las que hereda.
Polimorfismo de métodos:
¾ Consiste en la posibilidad de llamar a un mismo método (mensaje) para diferentes clases y que,
dependiendo del objeto que lo reciba, actúe de distinta forma.
¾ Técnicamente consiste en averiguar la dirección donde se encuentra el código máquina con la
implementación del método que se desea ejecutar (enlazado o ligadura).
¾ Dependiendo de cuando se realice hablaremos de:
o Ligadura o enlace estático. Se realiza en tiempo de compilación y se identifica por el
tipo al que pertenece la variable que identifica, referencia o apunta al objeto.
o Ligadura o enlace dinámico (virtual). Se realiza en tiempo de ejecución. El método se
ejecutará dependiendo del tipo de la clase a la que pertenezca el objeto.
Clases abstractas
•
•
•
Una clase abstracta define un tipo de dato del cual NO SE PUEDEN crear objetos:
o Es necesario derivar subclases que sí permitan la definición de objetos.
o Pueden declararse punteros y referencias.
o Tienen uno o más métodos abstractos o virtuales puros.
La clase abstracta obliga a todas las subclases a:
o Compartir estado (atributos) y comportamiento (métodos).
o Redefinir de forma particularizada en cada subclase la forma de operar de los métodos
abstractos.
Una clase virtual pura es la que todos sus métodos son abstractos.
Abad Vich David y Benítez Pedrero Jesús Alejandro Página 4 Programación Orientada a Objetos Interfaces
¾ Una interfaz describe el comportamiento o las capacidades de una clase sin hacer referencias a
una implementación en particular.
¾ Representa un contrato entre el proveedor (clase abstracta) y sus usuarios (clases derivadas)
donde se especifica lo que debe implementarse para satisfacer la interfaz.
¾ Definen una forma de polimorfismo entre objetos de clases no relacionadas en el modelo
conceptual.
¾ En C++ se utilizan haciendo uso de clases abstractas y herencia múltiple.
¾ En Python no existen interfaces.
RTTI (Run Time Type Identification)
Al utilizar polimorfismo de objetos a través de punteros o referencias, en ciertas circunstancias, es
necesario conocer en tiempo de ejecución el tipo al que pertenece un objeto.
Previo a objetos
Antes de meternos de lleno en objetos con Python, primero debemos comentar como se realizan las
asignaciones y las funciones.
A diferencia de C++, Python no necesita indicar el tipo de elemento que declara, recordemos que es un
lenguaje interpretado, lo que le permite detectar el tipo en tiempo de ejecución.
En C++
int entero = 12;
char car = a;
string cad = “Hola”;
float dec = 27,5;
long int largo = 349;
En Python
entero = 12
car = “a”
cad = “Hola”
dec = 25.5
largo = 349L
A partir de la versión 2.2 de Python, las operaciones con enteros que provoquen desbordamiento son
automáticamente realizadas con enteros largos:
2**30
2**31
1073741824
2147483648L
Para definir una función en Python usamos la palabra reservada def seguida del nombre de la función,
parámetros y los dos puntos.
def saludaNveces(n):
for i in n:
print(“Hola {}”.format(i))
Esta función de ejemplo imprimirá por pantalla “Hola i” las n veces que le indiquemos en la llamada.
Abad Vich David y Benítez Pedrero Jesús Alejandro Página 5 Programación Orientada a Objetos Clases en Python
A diferencia de C++, en Python no se pueden declarar atributos protegidos dentro de las clases, pero
podemos seguir declarando atributos públicos y privados. Sin embargo los atributos privados tienen una
cierta peculiaridad y es que tú puedes definir para los mismos una función 'get' para luego llamar al
atributo privado como si fuese público, pero lo devuelve de la forma que hemos especificado en el 'get'.
Veamos un ejemplo de declaración de una clase en Python:
class Humano:
def __init__(self,nombre, edad):
self. nombre = nombre
self.__ edad = edad
self.color = “blanco”
Además de la clase, también hemos definido lo que podríamos llamar como constructor por defecto, sin
embargo, ¡ojo!, ¡no se trata de un constructor por defecto! Hay que evitar referirse a él como tal.
Como decíamos, el 'init' se utiliza para declarar los atributos con los que empieza nuestra clase.
¿Qué pasa si no definimos un ´constructor por defecto´?
Entonces la clase se crea sin atributos y métodos, de forma que es perfecta para ir añadiendo luego los
atributos y métodos que creamos convenientes (esto se verá en los siguientes apartados).
Las instancias de esa clase serán de la forma:
persona = Humano(“Mace Windu”,27)
El acceso a los atributos y métodos de la clase es similar a C++, por ejemplo si queremos acceder al
“color” escribiremos:
persona.color = “negro”
Puesto que no hemos definido el 'get', aún no podemos acceder al segundo atributo de forma normal.
Podríamos acceder poniendo el nombre de la clase justo antes del atributo:
persona._Humano__edad = 36
Ahora añadimos a nuestra anterior clase las siguientes líneas de código:
def get_edad(self):
return self.__edad
def set_edad(self,valor):
self.__edad = valor
edad = property(get_edad,set_edad)
Ahora ya podemos acceder al segundo atributo como si fuese público, aunque accedemos de la forma que
hemos definido en el 'get'.
Abad Vich David y Benítez Pedrero Jesús Alejandro Página 6 Programación Orientada a Objetos Constructor copia
Python no tiene constructores de copia puesto que todo va por asignación; si intentas crear un objeto
copiándolo de otro el resultado serán dos objetos diferentes compartiendo los mismos atributos; como si
en C++ tuviéramos dos objetos que tuvieran un puntero a un mismo atributo.
Destructores
Si crear instancias nuevas es sencillo, destruirlas lo es más. En general, no hay necesidad de liberar de
forma explícita las instancias, porque se eliminan automáticamente cuando las variables a las que se
asignan salen de ámbito. Son raras las pérdidas de memoria en Python; todo es gracias al recolector de
basura.
Al igual que en C++ podemos redefinir los diferentes tipos de operadores estándar, a continuación una
lista de operadores y de la función que tenemos que redefinir dentro de la clase:
Operador
x<y
x<=y
x==y
x!=y
x>y
Cabecera función
x.__lt__(y)
x.__le__(y)
x.__eq__(y)
x.__ne__(y)
x.__gt__(y)
x>=y
x.__ge__(y)
Herencia y herencia múltiple
En Python contamos también con la posibilidad de que una clase herede de otra, e incluso que herede de
más de una. Mientras que en C++ tenemos los tres posibles tipos de herencias (pública, protegida y
privada), en Python solamente contamos con el tipo de herencia pública. De forma parecida a C++,
indicamos al lado la clase padre de la que hereda.
class Jedi(Humano):
def ….
De la misma forma, podemos heredar de más de una clase añadiéndola.
class Sith(Humano):
def ….
class Skywalker(Jedi,Sith):
def ….
Aprovechamos para indicar que cuando una clase hereda de dos, las cuales heredan de otra, entonces en
la última clase hija los atributos de la primera clase padre no se repiten. Esto quiere decir que el tipo de
herencia es además virtual, lo que también se aplica a los métodos de clase.
Herencia de tipo virtual
Tal y como decíamos al final del apartado anterior, el tipo de herencia, además de pública, es virtual. Por
lo que implica que si una clase hija “repite” atributos o métodos de la clase padre, se van a tomar como
buenos los de la clase hija, aunque en los métodos de la clase hija se puede llamar a los del padre, sin
embargo no podemos llamar a los métodos de la clase padre fuera de los métodos de la clase hija.
Abad Vich David y Benítez Pedrero Jesús Alejandro Página 7 Programación Orientada a Objetos En el siguiente diagrama queda todo más claro.
Polimorfismo
Ya que Python es un lenguaje interpretado, siempre se realiza polimorfismo ya que en tiempo de
ejecución podemos saber si un atributo o método a qué clase pertenece o qué tipo de clase es y sus
restricciones ya que nos da información sobre ellos; por lo cual el polimorfismo no lo podemos “forzar” y
es como si siempre estuviera presente; y como ya hemos comentado de que es un lenguaje interpretado no
existiría ligadura estática (ya que no es un lenguaje compilado), sino que siempre habría ligadura
dinámica, la cual se resuelve en tiempo de ejecución.
Módulos
Existen muchas propiedades que se pueden agregar al lenguaje importando módulos, que son minicódigos
(la mayoría escritos también en Python) que llaman a los recursos del sistema. Un ejemplo es el módulo
Tkinter, que permite crear interfaces gráficas que incluyan botones, cajas de texto, y muchas cosas que
vemos habitualmente en el sistema operativo. Otro ejemplo es el módulo que permite manejar el sistema
operativo desde el lenguaje. Los módulos se agregan a los códigos escribiendo import seguida del nombre
del módulo que queramos usar. En este código se muestra como apagar el ordenador desde Windows.
apagar = "shutdown /s"
import os
os.system(apagar)
Instropección
Python dispone de una función que te muestra las funciones y métodos de una clase, es la función dir ,
además podemos definir en nuestra clase un método __dir__ para indicar los métodos de los que dispone
la clase; por ejemplo:
def __dir__(self):
return[‘get_edad’, ‘set_edad’]
Entonces cuando definamos un nuevo objeto de la clase, al usar el dir, devolverá que contiene los
métodos ‘get_edad’ y ‘set_edad’.
Saber si un objeto pertenece a una clase es fácil, pues Python incorpora una función que devuelve en un
dato bool si el objeto pertenece o no.
padme = Humano()
isinstance(padme, Humano)
Abad Vich David y Benítez Pedrero Jesús Alejandro Página 8 Programación Orientada a Objetos Devolverá un true, pues es un objeto de esa clase.
luke = Skywalker()
isinstance(luke,Jedi)
También devolverá un true, pues un Skywalker es un Jedi, sin embargo en el caso contrario nos
devolvería un false como bien ya sabemos.
Python incluye otra función más para saber si una clase es hija de otra, devolviendo un true o false según
corresponda, sigue la siguiente sintaxis:
issubclass(Jedi,Humano)
Esto es equivalente a la RTTI en C++, facilitando un poco la tarea ya que no tenemos que comparar nada.
Añadir atributos y métodos a una clase en tiempo de ejecución
Una de las ventajas de los lenguajes interpretados frente a los compilados es la posibilidad de añadir
atributos y/o métodos a una clase en tiempo de ejecución. En Python es más sencillo de lo que en un
principio parece.
Primero vamos con añadir un atributo, función que Python trae ya hecha:
setattr(clase, 'nombre del atributo',valor inicial)
Por ejemplo:
setattr(Jedi,'color_sable',“Verde”)
Añadir un método es aún más sencillo, sólo tenemos que definir el método primero y luego añadirlo a la
clase.
def cambiaSable(self,color):
self.color_sable = color
Jedi.cambiaSable = cambiaSable
Y ya podemos usar ese método con cualquier objeto de la clase.
luke.cambiaSable(azul)
Como ya sabemos, C++ es compilado, por lo que no cuenta con esta capacidad.
Excepciones
Cuando hay un error de ejecución, Python emite lo que se llama una excepción. Por ejemplo:
i=5
while i>-2:
print 100/i,
i=i-1
20 25 33 50 100
Traceback (most recent call last):
File "<stdio>", line 2, in <module>
ZeroDivisionError: integer division or modulo by zero
Abad Vich David y Benítez Pedrero Jesús Alejandro Página 9 Programación Orientada a Objetos El mensaje indica que se ha producido una excepción y su tipo. Además indica en qué fichero se ha
producido y da una traza de las llamadas. Esto es muy útil para depurar programas.
Si queremos controlar las excepciones, podemos hacerlo mediante la construcción try-except.
El significado de la construcción es el siguiente. Se ejecutan las sentencias asociadas a la parte try hasta
que analicen normalmente o se produzca alguna excepción. En el primer caso, la ejecución continúa en la
sentencia siguiente al try-except. En caso de que se produzca una excepción, se interrumpe la ejecución.
Si la excepción coincide con la que se indica en el except, la ejecución continúa en las sentencias
asociadas a él; lo único que cambia con respecto a C++ es que en él se utiliza try catch; por ejemplo:
l=[2,0,10,12,0.0,8]
for i in l:
try:
print (i,1.0/i)
except ZeroDivisionError:
print (i,'no tiene inversa')
2 0.5
0 no tiene inversa
10 0.1
12 0.0833333333333
0.0 no tiene inversa
8 0.125
Si no se asocia ninguna excepción al except, este las capturará todas, lo que no es aconsejable ya que
puede enmascarar errores que no se tratan adecuadamente. Las excepciones también pueden tener un
valor asociado en el que se den detalles adicionales. Para capturarlo, basta con poner una variable detrás
del tipo de excepción:
try:
try:
a=1/0
except ZeroDivisionError,a:
print (a)
...
integer division or modulo by zero
a=1.0/0
except ZeroDivisionError,a:
print (a)
...
float division
Los programas también pueden generar las excepciones explícitamente mediante la orden
raise. Se le pasan uno o dos argumentos. El primero es el tipo de excepción, el segundo indica los
detalles:
raise ZeroDivisionError("esta es voluntaria")
Para crear una excepción, basta con definir una variable que contenga una cadena. Es costumbre que la
cadena sea igual al nombre de la variable:
miexc='miexc'
try:
raise miexc("funciona")
except miexc as va:
print (va.args[0])
...
Otra posibilidad, que es la recomendada, es crear una clase derivada de Exception:
class MiExcepcion (Exception):
# El método __init__ sirve
# como constructor:
def __init__(self, mensaje):
self.mensaje= mensaje
...
try:
raise MiExcepcion("Esto lo he lanzado yo")
except MiExcepcion as excepcion:
print (excepcion.mensaje)
...
Esto lo he lanzado yo
A la hora de tomar las excepciones, cualquier clase derivada de Exception puede ser cogida como un tipo
de excepción Exception.
Abad Vich David y Benítez Pedrero Jesús Alejandro Página 10 Programación Orientada a Objetos try:
raise MiExcepcion
except Exception as ex:
print(“Derivada de excepción”)
except MiExcepcion as mi:
print(“Excepción personal)
except:
print(“Cualquier excepción”)
Para coger cualquier excepción sea del tipo que sea, usamos simplemente el except sin ningún parámetro.
Esto es similar a los tres puntos que usamos en C++ para manejar cualquier excepción.
Plantillas
En Python no existen plantillas como tales puesto que cuando definimos una variable o función esta no
tiene un tipo predefinido; justo al contario pasa en C++ que toda variable o función tiene asociado un
tipo.
Hay que tener en cuenta que una clase en Python tiene que tener definidos los operador que sean
necesarios para la función.
Métodos de la librería CSV
Python incorpora una cómoda librería CSV para el manejo de este tipo de ficheros.
import csv
Una vez importada, podemos empezar a trabajar con ella. Vamos a ver la sintaxis para leer un archivo
.csv.
leer = csv.reader(open('ruta del archivo','forma de arbirlo',newline=''), delimiter='carácter
usado para separar los campos', quotechar='carácter usado para separar las diferentes líneas')
Al igual que en C++, disponemos de varias formas de abrir un archivo: 'r' sólo lectura, 'w' sólo escritura,
'a' para añadir al final del archivo y por último 'r+' para leer y escribir.
El carácter usado para separar los campos suele ser el espacio en blanco, aunque si no se le indica por
defecto toma la coma ','. De forma parecida, si no especificamos el quotechar, por defecto toma las
comillas '"'.
Este método lo que hace es devolver en leer un objeto del tipo reader, el cual está compuesto por las
diferentes filas del archivo por lo que para una lectura general bastará con hacer:
for fila in leer:
print(fila)
Y mostramos todas las filas del archivo.
Al abrir el archivo en modo escritura, especificamos lo mismo que en el de lectura.
escribir = csv.writer(open('jedis.csv','a',newline=''), delimiter=' ', quotechar=';')
escribe.writerow("Nombre: {} Color sable: {}".format(anakin.nombre,anakin.color))
Esto escribirá una nueva línea con el nombre y el color, separando cada palabra con un espacio (indicado
en el delmiter) y luego separará esa línea de las otras con un ';'.
Abad Vich David y Benítez Pedrero Jesús Alejandro Página 11 Programación Orientada a Objetos Ejemplos en Uml de un programa en Pyhton y el mismo en C++.
En Python++.
Abad Vich David y Benítez Pedrero Jesús Alejandro Página 12 Programación Orientada a Objetos En C++
Abad Vich David y Benítez Pedrero Jesús Alejandro Página 13