Download Tema 3. Paradigma Orientado a Objetos

Document related concepts
no text concepts found
Transcript
Lenguajes de Programación
Tema 3. Paradigma Orientado a
Objetos
Pedro García López
[email protected]/
Copyright
• © University Rovira i Virgili
• Permission is granted to copy, distribute and/or
modify this document under the terms of the GNU
Free Documentation License, Version 1.1 or any
later version published by the Free Software
Foundation; A copy of the license is available at:
•
http://www.fsf.org/licenses/fdl.html
Indice
•
•
•
•
Introducción
Paradigma Orientado a Objetos
Estudio de caso: Java
Conclusiones
Paradigma Orientado a Objetos
•
•
•
•
Conceptos generales
Clases y Objetos
Herencia
Polimorfismo
Problemas en la creación del software
¿Hay crisis del software?
• Gran complejidad
– Número de estados posibles es muy elevado
– Conexiones entre entidades
– Complejidad arbitraria que surge de instituciones
humanas
•
•
•
•
Sujeto a continuos cambios
No tiene representación gráfica
Especificación de requisitos
Comunicación del equipo
Calidad del Software
Factores Externos
•
•
•
•
•
Corrección
Robustez
Extensibilidad
Reutilización
Compatibilidad
Factores Internos
• Modularidad
• Legibilidad
•
•
•
•
Eficiencia
Portabilidad
Facilidad de uso
Funcionalidad
Mantenimiento del software
•
•
•
•
Parte noble: MODIFICACION
Parte no noble:
DEPURACION
Se le dedica el 70 % del coste del software
Distribución coste según [Lientz79]:
–
–
–
–
–
Cambios solicitados por los usuarios (41.8%)
Cambios en los formatos de los datos (17.4%)
Cambios de emergencia (12.4%)
Depuración rutinaria (9%)
Costes de documentación (5.5%)
Mantenimiento del software
• Conclusiones del estudio:
– Ausencia de extensibilidad
– Estructura física de los datos dispersa por
muchas partes del sistema
– No se hace documentación a posteriori
– Cuando el sistema funciona no se buscan
mejoras en eficiencia.
En los Sistemas Software interesa ...
Acoplamiento mínimo:
• Numero de conexiones
sea mínimo
• Flujo de información sea
mínimo
• Comunicaciones
explícitas
Cohesión interna:
• Cohesión de datos
• Cohesión funcional
Modulo A
Modulo B
Modulo C
Modulo A
Modulo B
Modulo C
Reutilización del software
• ¿Por qué el software no es como el
hardware?
• ¿Por qué cada nuevo proyecto software
arranca de la nada?
Librerías de software
Software-IC
Repetición en el desarrollo del
software
• ¿Cuántas veces en los últimos 6 meses has
escrito código para buscar un elemento en
una colección?
• Naturaleza repetitiva de la programación
(ordenar, buscar, recorrer, ...)
• ¿Por qué no es frecuente?
– Dificultades técnicas y no técnicas
Dificultades técnicas
• Diseñar código reutilizable es difícil.
• Hacemos las mismas cosas pero no de
la misma forma.
• Difícil captura de las similitudes.
• Permitir adaptación
Ejemplo
FUNCTION buscar (x: Elemento; c: Coleccion): BOOLEAN
VAR
pos : Posicion;
BEGIN
pos:= Comenzar (x,c);
WHILE not Completa (pos,c) and not Encontrado (pos, x, c) DO
pos:= Siguiente (pos, x, c);
buscar:= not Completa (pos,c);
END;
Rutina genérica para “búsqueda en una
colección”
Requisitos de los módulos para
facilitar la reutilización
FUNCTION buscar (x: Elemento; c: Coleccion): BOOLEAN
VAR
pos : Posicion;
BEGIN
pos:= Comenzar (x,c);
WHILE not Completa (pos,c) and not Encontrado (pos, x, c) DO
pos:= Siguiente (pos, x, c);
buscar:= not Completa (pos,c);
END;
1. Variación en tipos
Aplicable a diferentes tipos de elementos
x: Elemento
Requerimientos de los módulos
para facilitar la reutilización
FUNCTION buscar (x: Elemento; c: Coleccion): BOOLEAN
VAR
pos : Posicion;
BEGIN
pos:= Comenzar (x,c);
WHILE not Completa (pos,c) and not Encontrado (pos, x, c) DO
pos:= Siguiente (pos, x, c);
buscar:= not Completa (pos,c);
END;
2. Variación en estructuras de datos y
algoritmos
El tipo Coleccion puede estar implementado de diferentes formas y
Siguiente(pos,x,c) puede estar ligado a diferentes rutinas:
FAMILIAS DE MODULOS relacionados
Requerimientos de los módulos
para facilitar la reutilización
FUNCTION buscar (x: Elemento; c: Coleccion): BOOLEAN
VAR
pos : Posicion;
BEGIN
pos:= Comenzar (x,c);
WHILE not Completa (pos,c) and not Encontrado (pos, x, c) DO
pos:= Siguiente (pos, x, c);
buscar:= not Completa (pos,c);
END;
3. Independencia de la representación
Se puede usar una operación sin conocer su
implementación
siguiente(pos,x,c), comenzar(x,c),
encontrado(pos,c), completa(pos,c)
Independencia de la
representación
Alternativa:
if “c es de tipo A” then
“aplicar algoritmo de búsqueda A”
elseif “c es de tipo B” then
“aplicar algoritmo de búsqueda B”
elseif …
• Este código sería incluido en:
– Un único módulo: Grande y sujeto a constantes
cambios
– Código cliente: Dificulta la extensibilidad
Requerimientos de los módulos para
facilitar la reutilización.
FUNCTION buscar (x: Elemento; c: Coleccion): BOOLEAN
VAR
pos : Posicion;
BEGIN
pos:= Comenzar (x,c);
WHILE not Completa (pos,c) and not Encontrado (pos, x, c) DO
pos:= Siguiente (pos, x, c);
buscar:= not Completa (pos,c);
END;
4. Factorizar comportamientos comunes dentro
de una familia de implementaciones
5. Rutinas relacionadas
Ejemplo: Factorizar
comportamientos comunes
Tabla
Secuencial
Lista
Conjunto
Array
Fichero
Secuencial
• La operación “búsqueda” se escribe una
sola vez.
FUNCTION busqueda (x: elemento; t:Secuencia): BOOLEAN
BEGIN
Comenzar;
WHILE not Completa and not Encontrado(x) DO
Avanzar;
busqueda:=not Completa;
END;
ARRAY
Comenzar
Avanzar
Completa
Encontrado
i:=1
i:=i+1
i>tamaño
t[i] = x
LISTA
ENLAZADA
l:=cabeza
l:=l^.next
l=nil
l^.item = x
FICHERO
SECUENCIAL
reset
read
eof
f^= x
Una nueva variante sólo tiene que especificar cómo
implementar estas cuatro rutinas
Estructuras modulares
tradicionales
• Rutinas
• Paquetes o Módulos
¿Por qué no son suficientes?
Posibles soluciones para darles flexibilidad:
• Sobrecarga
• Genericidad
¿cubre los requisitos de módulos
reutilizables?
Rutinas
• Unidad de software que puede llamar a otras unidades
para ejecutar un cierto algoritmo.
• Enfoque de reutilización: librerías de rutinas
• Adecuadas en áreas donde pueden ser identificado un
conjunto de problemas individuales con las siguientes
limitaciones:
1. Admiten especificación simple: pequeño conjunto de
parámetros.
2. No estén implicadas estructuras de datos complejas.
3. Problemas claramente diferenciados.
Limitaciones de las rutinas
• Soluciones para: "Búsqueda en una colección secuencial”:
1) Una rutina:
• "CASE" enorme.
• Muchos argumentos.
2) Conjunto de rutinas:
• Rutinas muy similares ( factorizar comportamiento)
• Cliente debe buscar en un laberinto de rutinas.
Conclusión: Un módulo reutilizable debe estar abierto a la
adaptación y, la única forma de adaptación de una
rutina es pasarle diferentes argumentos.
Las rutinas no son suficientemente flexibles
Paquetes/Módulos
• Son unidades de descomposición de software que:
– Cumplen el principio de Unidad Lingüística Modular
– Contienen variables y rutinas relacionadas = características
del `paquete
– Admiten la Ocultación de la Información (módulos
abstractos)
– Permite la implementación de tipos definidos por el
programador
• Los módulos sólo resuelven ”rutinas relacionadas”
– facilita depuración y cambio al proveedor
– es más fácil para los clientes encontrar y usar los servicios de
los módulos
Ejemplo: Paquetes/Módulos
Package TablaEnteros;
type ArbolBinEnteros
record
info: Integer
izq, der: ArbolBinEnteros
end;
PAQUETE
DECLARACIÓN DE TIPO
new: ArbolBinEnteros begin … end;
OPERACIONES
añadir(t:ArbolBinEnteros; x: Integer) begin … end;
SOBRE EL TIPO
existe(t:ArbolBinEnteros; x: Integer): Boolean begin ..
end
….
end
Sobrecarga
• Identificador con más de un significado.
• Ejemplo: Sobrecarga de rutinas
FUNCTION Búsqueda (x:Cuenta; t: ListaCuentas): Boolean;
FUNCTION Búsqueda (x:CHAR; t: ARRAY [CHAR]): Boolean;
FUNCTION Búsqueda (x:REAL; t: ARRAY[REAL]): Boolean;
• Facilidad sintáctica orientada a los clientes.
• Permite escribir el mismo código cliente usando
diferentes implementaciones de cierto concepto.
¿Qué nos proporciona la
sobrecarga?
• ¿ Resuelve “Variación en estructuras de datos y
algoritmos”?
• ¿Resuelve “Independencia de la representación”?
• En cada invocación “Busqueda(x,t)” cliente y
compilador saben de que versión se trata.
• “Independencia en la representación” exige poder
escribir “Busqueda(x,t)” significando:
“Busca x en t usando el algoritmo adecuado,
cualesquiera que sea la clase de colección ligada a t
en tiempo de ejecución”
Genericidad
• Posibilidad de definir módulos parametrizados, cuyos
parámetros representan tipos.
• Facilidad orientada a los creadores de módulos permite
escribir el mismo código cuando se usa la misma
implementación de cierto concepto, aplicado a
diferentes tipos de objetos” Ej:
Array
[T],
Lista[T]
• Los módulos cliente deben instanciar el módulo
genérico
Ej: Array [Real],
Lista[Figura],
• Resuelve “variación en tipos”
Ejemplo de Genericidad
Package Tabla[T];
type ArbolBinario
record
info: T
izq, der: ArbolBinEnteros
end;
new: ArbolBinario begin … end;
añadir(t:ArbolBinario; x: T) begin … end;
existe(t:ArbolBinario; x: T): Boolean begin .. end
….
end
Conclusión
• La genericidad resuelve:
Variación en tipos.
• Los paquetes/modulos resuelve:
Rutinas relacionadas.
• No se resuelve:
Variación en estructuras de datos y algoritmos.
Independencia de la representación.
Capturar similitudes entre un subgrupo de un
conjunto de posibles implementaciones.
Descomposición Funcional
A
B
Secuencia
D
C
Condicional
Bucle
E
F
G
H
Inconvenientes de la
Descomposición Funcional
• Función principal: “Cima del sistema”
– El “programa principal” es una propiedad
volátil
– Sistemas reales no tienen “cima”
– Mejor la visión de un “conjunto de servicios”
• Centrado en la interfaz
– Primera pregunta: ¿Que hará el sistema?
– La arquitectura del software debe basarse en
propiedades más profundas.
• Ordenación temporal prematura
Inconvenientes de la
Descomposición Funcional
• No favorece la reutilización
– Se desarrollan elementos software para satisfacer
necesidades específicas de otro elemento del nivel
superior.
– “Cultura del proyecto actual”
• Las estructuras de datos son descuidadas
– Funciones y datos deben jugar un papel
complementario
• Cuando un sistema evoluciona los datos son
más estables que los procesos.
Ventajas de la Descomposición
Funcional
• Técnica simple, fácil de aplicar
• Util para pequeños programas y describir
algoritmos.
• Buena para documentar diseños.
• Facilita desarrollo sistemático de sistemas
• Adecuada para dominar la complejidad
Descomposición basada en
objetos
• Los objetos son más estables que las
funciones cuando el sistema evoluciona
(Extensibilidad).
• Tipos de objetos equipados con las
operaciones asociadas (Reutilización).
• El diseñador lista las operaciones aplicables
a cierto tipo de objetos, especificando su
efecto.
• Se retrasa todo lo posible el orden en que se
ejecutan las operaciones.
Desarrollo software OO
1. Encontrar tipos de objetos relevantes
2. Encontrar operaciones para tipos de objetos
3. Describir tipos de objetos
4. Encontrar relaciones entre objetos
5. Usar tipos de objetos para estructurar
software
Conceptos Clave POO
•
•
•
•
•
•
•
•
•
•
•
Clase y Objeto
Clase: Atributos y métodos
Creación de clases: constructores e instanciación
Invocación de métodos
Atributos y métodos de clase
Ocultación de información
Tipos referencia, asignación, aliasing y copia de
objetos
Concepto de Metaclase
Relaciones entre clases: clientela y herencia
Tipos de herencia
Polimorfismo y ligadura dinámica
Clases y Objetos
Una clase es un módulo y un tipo de dato:
• Módulo (concepto sintáctico)
– Mecanismo para organizar el software (sintáctico)
– Encapsula componentes software
• Tipo (concepto semántico)
– Mecanismo de definición de nuevos tipos de datos:
describe una estructura de datos (objetos) para representar
valores de un dominio y las operaciones aplicables.
Combinación módulo-tipo
“Los servicios proporcionados por una clase,
vista como un módulo, son precisamente las
operaciones disponibles sobre las instancias
de la clase, vista como un tipo”.
• Como cada módulo es un tipo, cada operación
del módulo es relativa a cierta instancia del
tipo
TAD y Clase
Teoría
TAD
{Operaciones: Sintaxis
y Semántica}
Software
Clase
{Elegir representación e
implementar operaciones}
Clases: Ejemplo
• Al modelar un banco, encontramos objetos
“cuenta”.
• Todos los objetos “cuenta” tienen unas
propiedades comunes:
– saldo, titular, código, reintegro, ingreso, …
• Definimos una clase Cuenta.
• Clases del dominio y clases de
diseño/implementación
Componentes de un clase
• Atributos
– Determinan una estructura de almacenamiento
para cada objeto de la clase
• Rutinas (Métodos)
– Operaciones aplicables a los objetos
– Único modo de acceder a los atributos
Ejemplo: Al modelar un banco, encontramos objetos “cuenta”.
Todos los objetos “cuenta” tienen propiedades
comunes:
• atributos: saldo, titular, ...
• operaciones: reintegro, ingreso, …
Definimos una clase CUENTA.
Cada objeto es instancia de
una clase
Estructura de datos
Código
Objeto Cuenta
Objeto Cuenta
Clase Cuenta
Instanciación
Objeto Cuenta
Objeto Cuenta
Cuenta oc
oc = new Cuenta()
Cada objeto es instancia directa de una clase.
Una clase es una factoría de objetos
Constructores (C++ y Java)
• Realizan la inicialización de un objeto tras la
creación.
• Un constructor
– procedimiento especial con el mismo nombre que
la clase.
– Se debe invocar cuando se crea un objeto de la
clase con el operador new
– En C++ también cuando se declara una variable.
– Pueden tener modificadores de acceso
Mensajes
• Mecanismo básico de la computación OO.
• Invocación de la aplicación de un método sobre un
objeto.
• La modificación o consulta del estado de un objeto
se realiza mediante mensajes.
• Formado por tres partes
– Objeto receptor
– Selector o identificador del método a aplicar
– Argumentos
Semántica mensajes
• Sea el mensaje x.f, su significado es:
“Aplicar el método f sobre el receptor x,
efectuando el paso de parámetros”
¡NO CONFUNDIR CON LA INVOCACIÓN
DE UN PROCEDIMIENTO!
Variables y métodos de Clase
• Compartida por todas las instancias de una
clase.
• Registrar valor común a todas las instancias
• Ejemplos para una clase Cuenta:
– Interés, Coste tarjeta, Último código asignado
• ¿Cuándo se inicializa?
• Puede ser accedida por métodos de
instancia y de clase
• Los métodos de clase no deberían acceder a
variables de instancia
Clases y Ocultación de
Información
• Ocultamiento información importante para
conseguir arquitecturas flexibles y coherentes.
• Interface vs. Implementación:
– Un cliente sólo conoce la interface.
– Sólo los métodos de la clase deberían poder acceder a
sus atributos.
• Cada lenguaje OO (Eiffel, C++, Java, Smalltalk)
presenta diferencias en cuanto al ocultamiento de
información.
Tipos referencia
• Los posibles valores de una entidad (atributo,
parámetro, …) son referencias a objetos potenciales
que pueden ser creados en tiempo de ejecución a
través, siempre, de instrucciones de creación
explícitas.
• Una referencia puede encontrarse en uno de dos
estados posibles
– No ligada: Void (Eiffel) o null (Java)
– Ligada a un objeto
• Las referencias son “punteros domesticados”.
• Void es un estado (null es un literal) mientras que “nil”
(en Pascal) o “null” (en C) son valores de tipo puntero.
Ventajas de los tipos referencia
• Más eficiente para manejar objetos complejos.
• Soporte para definir estructuras de datos recursivas.
• Soporte del polimorfismo.
• Los objetos son creados cuando son necesarios.
• Permite la compartición de un objeto (integridad
semántica).
• DESVENTAJA: “Aliasing”
Asignación
ob
oa
oa:= ob
oa
ob
La asignación no implica copia de valores sino de
referencias
¡Cuidado con el
Aliasing!
Solución: Copia de objetos
• Copia superficial
– Se copian los valores de cada campo del objeto
origen oy en el objeto destino ox; ox y oy
comparten referencias.
– Soportada por defecto y puede redefinirse para
una clase concreta.
• Copia profunda
– Se crea un objeto con una estructura idéntica al
objeto origen.
– No hay compartición de referencias
– No suele ser soportada por defecto
Metaclases
• Una clase puede ser considerada un objeto:
– ¿Cuál es su clase?
• Metaclase
– Clase que describe clases, sus instancias son
clases.
– Propiedades: lista de atributos, lista de variables
de clase, lista de métodos, lista de métodos de
clase.
• Java y Smalltalk tienen metaclases
• Útil en programación avanzada, cuando se manejan
entidades software, p.e. depuradores, inspectores,
browsers,..
Relaciones entre clases
• Clientela
Una clase A es cliente de una clase B, si A contiene
una declaración en la que se establezca que cierta
entidad (atributo, parámetro, variable local) e es de
tipo B (e:B)
CUENTA
Ejemplo:
• Herencia
titular: Persona
PERSONA
“Cuenta es cliente de Persona”
Una clase es una versión especializada de otra
existente
Cuenta
Ejemplo:
CuentaAhorro
CuentaCorriente
Herencia
La herencia organiza las clases en una estructura jerárquica:
Jerarquías de clases
Ejemplos:
PUBLICACION
LIBRO
LIBRO_TEXTO
REVISTA
INVESTIGACION MAGAZINE
FIGURA
POLIGONO
RECTANGULO
• No es tan solo un mecanismo para compartir código.
• Consistente con el sistema de tipos del lenguaje
CIRCULO
Herencia
• Puede existir una clase “raíz” en la jerarquía de la
cual heredan las demás directa o indirectamente.
• Incluye todas las características comunes a todas
las clases
Eiffel:
Smalltalk:
Java:
C++:
clase ANY
clase Object
clase Object
no existe
Herencia
Si B hereda de A entonces B incorpora la estructura (atributos) y
comportamiento (métodos) de la clase A, pero puede incluir
adaptaciones:
-B puede añadir nuevos atributos
-B puede añadir nuevos métodos
•Refinamiento: Extender el uso original
-B puede REDEFINIR métodos
•Reemplazo: Mejorar la implementación
-B puede renombrar atributos o métodos
- B puede implementar un método diferido en A
…
Adaptaciones dependientes del lenguaje
(Redefinición disponible en cualquier LOO)
Polimorfismo
• Es restringido por la herencia
• Importante para escribir código genérico
• Sea las declaraciones:
ox: X; rutina1 (oy:Y)
– En un lenguaje con monomorfismo (Pascal, Ada, ..)
en t.e. ox y oy denotarán valores de los tipos X e Y,
respectivamente.
– En un lenguaje con polimorfismo (Eiffel, C++, ..) en
t.e. ox y oy podrán estar asociados a objetos de varios
tipos diferentes:
tipo estático vs. tipo dinámico
Tipo estático y tipo dinámico
• Tipo estático:
– Tipo asociado en la declaración
• Tipo dinámico:
– Tipo correspondiente a la clase del objeto conectado a
la entidad en tiempo de ejecución
• Conjunto de tipos dinámicos:
– Conjunto de posibles tipos dinámicos de una entidad
Ejemplo:
A
B
D
C
E
F
oa: A; ob: B; oc; C;
te(oa) = A
ctd(oa) =
{A,B,C,D,E,F}
te(ob) = B
ctd(ob) = {B, D, E}
te(oc) = C
ctd(oc) = {C,F}
p
(antes)
(después)

Conexión polimorfa
(POLIGONO)
r
p:POLIGONO; r:RECTANGULO
(RECTANGULO)
• Cuando el origen y el destino tiene tipos diferentes:
a) asignación:
p := r;
polimorfa
-- p es una entidad
b) paso de parámetros:
f (p:POLIGONO) is do ... end
polimorfa
-- f es una rutina
• Sólo se permite para entidades destino de tipo
referencia
Tipos de polimorfismo
• Real
– Paramétrico (“lista de T”)
– Inclusión:
• Basado en la herencia
• una función y varias interpretaciones diferentes
• Aparente
– Sobrecarga
• varias funciones todas con el mismo nombre
Ejemplo polimorfismo paramétrico:
long (l:lista): integer
if l=nil then long:=1
else long:= 1 + long(cola(l))
Sobrecarga
• Es el nombre de la función lo que es polimórfico
• Se resuelve en tiempo de compilación, según la
signatura de la rutina.
• No es necesario que exista similitud semántica.
• En los lenguajes OO puede existir sobrecarga
– dentro de una clase
– entre clases no relacionadas (es fundamental)
Polimorfismo y código genérico
• Estructuras de datos polimórficas:
Pueden contener instancias de una jerarquía de clases
• Ejemplo:
p: POLIGONO;
r: RECTANGULO;
c: CIRCULO;
t:TRIANGULO;
!!p; !!r; !!c; !!t;
fig.put (p,1);
fig.put (r,2);
fig.put (c,3);
fig.put (t,4); ...
fig: ARRAY [FIGURA]
fig
1
2
3
4
Genericidad
• ¿Cómo escribir una clase que represente una
estructura de datos y que sea posible almacenar
objetos de cualquier tipo?
Pila-Enteros
Pila_Libros
 Pila de ?
Pila_Figuras
….
• Necesidad de reconciliar reutilización con el
uso de un lenguaje tipado.
Herencia
ColeccionEntero
ColeccionTarea
ListaEntero
GrafoTarea
ListaCircularEntero
RedTarea
class ListaEntero inherit ColeccionEntero
feature
numElements: Integer is do ..
añadir (i: Integer, v:Integer) is do ..
iesimo (i:Integer): Integer is do ..
buscar (v:Integer): Boolean is do ..
...
end
¿Cómo asociar a v un tipo pero sin hacer que
la clase sea dependiente del tipo de objeto
almacenado?
Genericidad
Coleccion [G]
Lista [G]
ListaCircular [G]
class Lista [G] feature
numElements. Integer is do ..
añadir (i: Integer, v:G) is do ..
iesimo (i:Integer): G is do ..
buscar (v:G): Boolean is do ..
...
end
miLista1: Lista [Integer]
miLista2: Lista [Punto]
Genericidad
• Posibilidad de parametrizar las clases; los
parámetros son tipos de datos.
• Facilidad útil para las clases que representan
estructuras de datos generales: TIPO BASE ES
UN PARAMETRO
class ARRAY [G], class PILA [G],
[G], ...
class LISTA
• Orientada a los creadores de clases
Estudio de caso: Java
Lenguaje:
• Simple
• Orientado a Objetos
• Robusto
• Arquitectura-neutral (portable)
• Moderno
– librerias (+ APIs)
– excepciones
– (...)
Hola Mundo
/*
* Example HelloWorld
* Prints the message "Hello, World!“
*/
public class HelloWorld {
public static void main(String[] args) {
System.out.println("Hello, world.”);
}
}
Palabras reservadas
abstract
boolean
break
byte
byvalue
case
cast
catch
char
class
const
continue
default
do
double
else
extends
false
final
finally
float
for
future
generic
goto
if
implements
import
inner
instanceof
int
interface
long
native
new
null
operator
outer
package
private
protected
public
rest
return
short
static
super
switch
synchronized
this
throw
throws
transient
true
try
var
void
volatile
while
Tipos Simples
Tipos Simples
Tamaño
Valor Mínimo
Valor Màximo
Tipos Wrapper
boolean
1-bit
-
-
Boolean
char
16-bit
Unicode 0
Unicode 216-1
Character
byte
8-bit
-128
+127
Byte
short
16-bit
-215
+215-1
Short
int
32-bit
-231
+231-1
Integer
long
64-bit
-263
+263-1
Long
float
32-bit
IEE754
IEE754
Float
double
64-bit
IEE754
IEE754
Double
void
-
-
-
Void
Bloques
Comandos y secuenciadores
if (expressBool) {
....
} else {
....
}
switch (selector) {
case valor1: instrucció1;
break;
selector:
case valor2: ...........
char,byte,short,int
...
default: instruccióN;
}
Comandos y Secuenciadores
• Bucles FOR:
for (<inicialització>; <continuar si
...>;<increment>)
for (int i=0; i<10; i++) {...}
• Bucles DO-WHILE
do {
...
} while (expressioBooleana);
• Bucles WHILE
while (expressioBooleana) {
...
}
Clases en Java
• Lenguaje tipado estáticamente
• Legible
• No separación en fichero interfaz e
implementación.
• Lenguaje interpretado: Máquina Virtual Java
• Atributos y variables de clase
• Métodos de instancia y de clase
• Incluye metaclases (Reflexión)
Ejemplo: Cuenta
class Cuenta {
private String
private int
private int
private int[]
titular;
saldo;
codigo;
ultOper;
private static int
ultimoCodigo = 0;
public static int nuevoCodigo () {return ++ultimoCodigo;}
public Cuenta (String quien) {
saldo=0; titular=quien;
codigo = nuevoCodigo(); ultOper = new int[100];}
public void reintegro (int suma) {
if (puedoSacar(suma)) saldo=saldo-suma;};
public void ingreso (int suma) {
saldo=saldo+suma;}
public int getSaldo () { return saldo; }
private boolean puedoSacar(int suma) {return (saldo >=suma);}
}
Creación de Objetos
• Acceso a las variables de instancia de la
clase mediante métodos de instancia (set y
get).
Cuenta c = new Cuenta (“pedro”);
c.reintegro(10000);
c.ingreso(20000);
int x = c.getSaldo();
“
Propiedades de clase: static
class Cuenta
{
private String titular;
public static int interes=3;
public int setInteres(int cantidadPts)
{
interes= cantidadPts
}
¿ Que ocurre ?
Propiedades de clase
• No podemos acceder desde variables de
clase a variables de instancia.
// Método de clase
public static int setInteres(int cantidadPts)
{
interes= cantidadPts
}
Propiedades de clase
public class HelloWorld {
public static void main(String[] args) {
Cuenta.setInteres(12);
Math.sqrt(9);
}
}
Las propiedades de clase son válidas para
todos los objetos de la clase.
Clases Java y Ocultación de
Información
• “package”
– accesible por las clases del paquete, no
accesible a los clientes del paquete
• public
– accesible por todas las clases
• private
– sólo accesible por los métodos de la clase
• protected
– accesible por las clases del paquete y por las
subclases
Visibilidad
The class itself
Clases del mismo
paquete
Subclases de otro
paquete
No-subclases de
otro paquete
packag
public protected
e
Si
Si
Si
private
Si
Si
Si
Si
No
Si
Si
No
No
Si
No
No
No
Asignación
• Un objeto asociado a una variable cambia
cuando se evalúa una expresión de
asignación.
variable = expresión
• Ejemplos:
c1:=new Cuenta();
saldo := saldo - cantidadPtas.
s:= c1.saldo();
rect := new Rectangulo(punto1, punto2);
miObjeto:= otroObjeto;
• El operador := no hace una copia del objeto
Asignación y cloning
Point p = new Point (1,1);
Point p2 = p;
p2.setLocation(120,120);
//Aliasing
System.out.println("Valor de p:" + p.getX());
System.out.println("Valor de p2:" + p2.getX());
Point p3 = (Point)p.clone();
p3.setLocation(40,40);
System.out.println("Valor de p:" + p.getX());
System.out.println("Valor de p3:" + p3.getX());
Copia en Java
• La clase Object incluye el método
protected Object clone( ) {..} ..}
que implementa una copia superficial.
• Para poder clonar objetos de una clase se
debe
– Declarar que implementa la interfaz Cloneable
– Redefinir y hacer público el método clone()
– Dejar la versión original (copia superficial) o
bien hacer una copia de mayor profundidad.
Paso de Parámetros
class PassByValue {
public static void modifyPoint(Point pt, int j)
{
pt.setLocation(5,5);
j = 15;
}
public static void main(String args[])
{
Point p = new Point(0,0);
int i = 10;
modifyPoint(p, i);
}}
//1
//2
//3
Concepto de Metaclase: RTTI
• Run Time Type Identification
• Object
– Class getClass()
• Class
–
–
–
–
getFields
getMethods
getName
(...)
Agrupación de clases: Package
•
•
•
•
package pedro.utils;
import pedro.utils.*;
import pedro.*; // No es jerárquico
import pedro.utils.Cosa;
Paquetes Java
–
–
–
–
–
–
java.lang --- general
java.awt --- GUI
java.io --- I/O
java.util --- utilities
java.applet --- applet
java.net --- networking
Tipos Wrapper
int a =1;
int b= 2*3;
Integer awrap = new Integer(a);
int x = awrap.intValue();
int y = Integer.parseInt("123");
String z = String.valueOf(y);
Arrays: Tipo parametrizable
int lista [] = new int[100];
lista[0]=1;
for (int i=0;i<lista.length;i++)
lista[i]=0;
int lista[] = {1,2,3,4};
Perro lista2 = new Perro[100];
lista2[0] = new Perro ();
Object lista3 = new Object [100][100];
Relaciones entre clases
Composicíón: Tiene - Un
Student
-name : String *
-gpa : float
*
Faculty
1
1
Address
-streetAddress : String
-city : String
-state : String
-zipCode : String
Relaciones entre clases
Herencia: Es -Un
Student
GraduateStudent
MasterStudent
PhDStudent
UndergraduateStudent
Clases abstractas
• Algún método no se implementa
• No podemos instanciar una clase abstracta
• La clase abstracta puede tener métodos no
abstractos
• La clase abstracta debe ser heredada.
public abstract class Figura
{
public abstract dibujar();
}
Herencia en Java
• public class X extends Y {...}
Sintaxis de clase
[ ClassModifiers ] class ClassName
[ extends SuperClass ]
[ implements Interface1, Interface2 ...] {
ClassMemberDeclarations
}
• La clase Object
• this y super
Polimorfismo
Animal a = new Animal();
Perro p;
a = p;
Object x;
Perro p = new Perro();
x = p;
Polimorfismo y castings
Vector list = new Vector();
String s = “lala”;
Perro p = new Perro();
list.add(p);
list.add(s);
Object x = list.elementAt(0);
Perro p2 = (Perro)list.elementAt(0);
Polimorfismo y ligadura dinámica
• Java es un lenguaje tipado estáticamente
• La ligadura de un mensaje a un método
concreto se realiza en tiempo de ejecución
• ¿Qué versión de perímetro se ejecuta
en cada mensaje?
f= new Poligono ();
f.perimetro();
r = new Rectangulo();
r.perimetro();
f=r;
f.perimetro();
{i}
{ii}
{iii}
Interfaces
• Son clases en las que todos las propiedades
son estáticas y finales y todos los métodos
son abstractos.
interface Persona
interface Perro
{
{
public void habla();
}
public void ladra();
}
Interfaces y herencia
public class Mutante implements Persona, Perro
{
public void habla()
{
System.out.println(“Soy una persona”);
}
public void ladra()
{
}
}
System.out.println(“GUAU”);
Interfaces y polimorfismo
Mutante m = new Mutante();
Persona p = m;
p.habla();
Perro p = m;
m.ladra();
Interfaces
class Prueba
{
public static void ladra (Perro p)
{ p.ladra();
{
public static void habla(Persona p)
{ p.habla()
}
Interfaces
Mutante m = new Mutante();
Prueba.habla(m);
Prueba.ladra(m);
Ejemplo código genérico
java.util.Collection
Collection
AbstractCollection
AbstractList
Vector
Stack
ArrayList
AbstractSet
LinkedList
ArraySet
HashSet
Ejemplo: código genérico
•
•
•
•
•
•
•
•
•
•
•
•
boolean add(Object)
boolean addAll(Collection)
void clear()
boolean contains(Object)
boolean containsAll(Collection)
boolean isEmpty()
Iterator iterator()
boolean remove(Object)
boolean removeAll(Collection)
boolean retainAll(Collection)
int size()
Object[] toArray()
Iteradores
•
•
•
•
boolean hasNext()
Object next()
void remove() [implementación opcional]
Por ejemplo:
public void escribir (Collection c) {
for (Iterator it=c.iterator();
it.hasnext();) {
System.out.println(it.next());
}
}
Genericidad y Java
• Java no posee genericidad (hasta el Jdk1.5)
• Necesidad de declaraciones de tipo Object
• Problemas:
– Necesidad de conversiones de tipo
– No se asegura homogeneidad
• Incluye genericidad para arrays
private Cuenta[ ] cuentas = new
Cuenta[100]
private int[ ] valores = new int [4]
Estructuras de datos polimorfas
• Contiene objetos de diferentes clases
• Ejemplo: Array con cualquier variante de Figura
Figura conjFig = new Figura[10];
p= new Poligono();
r = new Rectangulo();
c = new Circulo();.
t = new Triangulo();
conjFig[0]=p;
conjFig[0]=r;
conjFig[0]=c;
conjFig[0]=t;
conjFig
1
2
3
4
Estructuras polimorfas y código
genérico
public void dibujarFiguras()
{
for (int i=0;i<conjFig.length;i++)
conjFig[i].dibujar();
}
Genericidad Restringida
• Es posible restringir las clases a las que se puede
instanciar el parámetro genérico formal de una clase
genérica.
class C [G -> R]
• Sólo es posible instanciar G con descendientes de la
clase R.
• Ejemplos:
VECTOR [G - > NUMERIC]
DICTIONARY [G, H - > COMPARABLE]
ORDENACION [G - > COMPARABLE]
• Permite aplicar operaciones sobre entidades cuyo
tipo es un parámetro genérico formal.
Genericidad en Java (JDK1.5)
• Basado en las templates de C++
• Se han rediseñado las colecciones de Java
para acomodar el código genérico
• Se han rediseñado los iteradores para
hacerlos más sencillos
• Permite genericidad restringida
Ejemplos genericidad
Nuevo iterador: for (Tipo elem: colección)
Ejemplos genericidad
Enumerados (JDK1.5)
Static Import (JDK1.5)
Excepciones Java
• “Proporcionan una manera limpia de comprobar
errores sin complicar el código”
• “Proporcionan, además, un mecanismo para señalar
directamente los errores sin necesidad de usar
indicadores (atributos, parámetros)”.
• “Son lanzadas cuando se detectan situaciones
imprevistas de error”.
Excepciones Java
BufferedReader br;
int codigoProducto = Integer.parseInt (br.readLine() )
• Puede suceder algo inesperado como que:
– br represente un fichero sobre un disco flexible que se ha extraído
– br represente una conexión en red y se produzca una caída de la
red
– br represente un fichero en mal estado sobre el disco duro
– el usuario introduzca un carácter no numérico
– el usuario introduce un código numérico incorrecto
Situaciones que deben ser manejadas por
excepciones
119
Excepciones Java
• Las excepciones son objetos.
• Hay dos tipos:
– Comprobadas
– No comprobadas
• Necesidad de definir subclases de Exception o
RunTimeException.
Jerarquía de Tipos de Excepciones
Java
Object
Throwable
Error
Exception
RunTimeException
No comprobadas
Comprobadas
Excepciones Comprobadas
• Subclases de Exception
• Un método que lance una excepción comprobada,
debe especificarlo en su signatura.
• El código que invoca un método que puede lanzar
una excepción comprobada debe manejarla
mediante una cláusula try-catch.
• Situaciones comprobadas por el compilador
Excepciones No Comprobadas
• Subclases de RuntimeException
• Un método puede lanzar una excepción no
comprobada, sin especificarlo en su signatura.
• El código que invoca un método que puede lanzar
una excepción no comprobada no debe manejarla.
• Es recomendable listar todas las excepciones en la
signatura para facilitar su uso.
¿Cómo elegimos si una nueva excepción es
comprobada o no comprobada?
123
Uso de Excepciones
Comprobadas
public class ClaveNoExiste extends Exception {
public ClaveNoExiste() { super(); }
}
// método en TablaHash
public void cambiarValor (String clave, Object valor)
throws ClaveNoExiste
{ if (obtener(clave) == null)
throw new ClaveNoExiste ();
…
}
TablaHash unaTabla;
...
try { unaTabla.cambiarValor(s,v);}
catch (ClaveNoExiste e) {...} finally {...}
124
Excepciones Comprobadas
¿Qué puede hacer el cliente de un método
que lanza una excepción comprobada?
1) Capturarla y manejarla
2) Capturarla y asociarla a una de las excepciones
declaradas en el método.
3) Declararla en la cláusula throws y no manejarla, con lo
que se propaga al método que lo invocó.
Excepciones No Comprobadas
¿Qué puede hacer el cliente de un método
que lanza una excepción no comprobada?
1) Si no la captura se propaga al método que lo invocó.
2) También puede capturarla y manejarla.
3) Capturar la excepción y asociarla a una de las
excepciones declaradas en el método.
Excepciones Java
try {
“Sentencias con mensajes que pueden provocar
excepciones”
} catch (unaExcepcion e) {“codigo manejo excepción”
} catch (OtraExcepcion e) {“codigo manejo excepción”
} finally {...} // se ejecuta se lance o no una excepción
Excepciones en Java
¡Una excepción
es un objeto!
try{
//sentencias
}catch (TipoExcepcion1 e){
//manejar excepción
}catch (TipoExcepcion2 e){
//manejar excepción
} ...
Ej: cerrar ficheros
finally{
//sentencias que se ejecutan SIEMPRE
//salte o no una excepción
}
Ejemplos
public static int factorial (int n) throws NonPositiveException
{
if (n<=0) throw new NonPositiveException (“Num.factorial”);
…
}
try { Num.factorial(y);
} catch (NonPositiveException e) { … }
Ejemplos
public static int search (int [] a, int x) throws NullPointerException
NoEncontradoException
{…}
try { …;
try { x = Arrays.search(v,7);}
catch (NullPointerException e) {
throw new NoEncontradoException(); }
} catch (NoEncontradoException e) {..}
¿Debo declarar NullPointerException en la signatura?
¿Es acertado considerar la situación de elemento no
encontrado como una excepción?
Captura de excepciones no
comprobadas
try { x = y [n]; i = Arrays.search(z, x);}
catch (IndexOutOfBoundsException e) {
“manejar la excepción en el caso del acceso y[n]” }
No se sabe la procedencia exacta de la excepción no
comprobada IndexOutOfBoundsException
Restringir el ámbito de la sentencia try
Ejemplos
public class Arrays {
public static int min (int [] a) throws NullPointerException,
EmptyException
{ // EFECTO: Si a es null lanza NullPointerException, si no si a
// está vacío lanza EmptyException, si no retorna el valor mínimo
// del array a
int m;
try { m = a[0]; }
catch (IndexOutOfBoundsException e) {
throw new EmptyException(“Arrays.min”); }
for (int i = 1; i < a.length; i++) if (a[i] < m) m = a[i];
return m; }
Ejemplos
public class Arrays {
public static boolean sorted (int [] a) throws
NullPointerException, EmptyException
{ // EFECTO: Si a es null lanza NullPointerException, si no retorna
// true si el array está ordenado en orden ascendente si no false
int prev;
try { prev = a[0]; }
catch (IndexOutOfBoundsException e) { return true; }
for (int i = 1; i < a.length; i++)
if (prev <= a[i]) prev = a[i]; else return false
return true; }