0% encontró este documento útil (0 votos)
259 vistas

Introducción A La Programación Orientada A Objetos PDF

Cargado por

Marco
Derechos de autor
© © All Rights Reserved
Nos tomamos en serio los derechos de los contenidos. Si sospechas que se trata de tu contenido, reclámalo aquí.
Formatos disponibles
Descarga como PDF, TXT o lee en línea desde Scribd
0% encontró este documento útil (0 votos)
259 vistas

Introducción A La Programación Orientada A Objetos PDF

Cargado por

Marco
Derechos de autor
© © All Rights Reserved
Nos tomamos en serio los derechos de los contenidos. Si sospechas que se trata de tu contenido, reclámalo aquí.
Formatos disponibles
Descarga como PDF, TXT o lee en línea desde Scribd
Está en la página 1/ 51

Programación orientada a objetos

“En vez de un procesador de celdas de memoria…


tenemos un universo de objetos de buen comportamiento
que cortésmente solicitan a las demás llevar a cabo sus deseos”
-- Ingalls, 1981 (revista Byte)

Evolución
Años 60 Simula
Resolución de problemas de simulación
© Ole-Johan Dahl & Krysten Nygaard (Noruega)
Años 70 Smalltalk
Entorno de programación entendible por “novatos”
© Alan Kay (Xerox PARC, Palo Alto, California)
Años 80 C++
Extensión de C
© Bjarne Stroustroup (AT&T Bell Labs)
Años 90 Java
“Write once, run everywhere”
© Sun Microsystems

Conceptos básicos
• Todo es un objeto
• Los objetos se comunican entre sí pasándose mensajes
• Cada objeto tiene un estado
(contiene su propia memoria [datos])
• Un objeto es un caso particular (instancia) de una clase
• Las clases definen el comportamiento de un conjunto de objetos

OOP – Introducción: Java -1- © Fernando Berzal


Resolución de problemas “con orientación a objetos”

Problema
Quiero enviar un paquete a un amigo que vive en otra ciudad

Opciones
a) Hacerlo todo yo mismo
˜ Descomposición en subproblemas
(programación estructurada)
b) Delegar en alguien para que lo haga (p.ej. Correos)
˜ “Realizar un encargo”
(programación orientada a objetos)

Solución orientada a objetos

• Se busca un objeto capaz de enviar un paquete


• Se le envía un mensaje con mi solicitud
• El objeto se hace responsable de satisfacer mi solicitud
• El objeto utiliza un algoritmo que yo no tengo por qué conocer

Consecuencias

• Un programa orientado a objetos se estructura como un conjunto


de agentes que interactúan (programa como colección de objetos).
• Cada objeto proporciona un servicio que es utilizado por otros
objetos (reutilización).
• La acción se inicia por la transmisión de un mensaje al objeto
responsable de realizarla.
• Si el receptor acepta el mensaje, acepta la responsabilidad de
llevar a cabo la acción solicitada.
• El receptor puede utilizar cualquier técnica que logre el objetivo
deseado.

OOP – Introducción: Java -2- © Fernando Berzal


Clases y objetos

Clase
Implementación de un tipo de dato.

Una clase sirve tanto de módulo como de tipo


- Tipo: Descripción de un conjunto de objetos
(equipados con ciertas operaciones).
- Módulo: Unidad de descomposición del software.

Objeto
Instancia de una clase:
Unidad atómica que encapsula estado y comportamiento.

• Un objeto puede caracterizar una entidad física (un teléfono, un


interruptor, un cliente) o una entidad abstracta (un número, una
fecha, una ecuación matemática).

• Todos los objetos son instancias de una clase: Los objetos se crean
por instanciación de las clases.

• Todos los objetos de una misma clase (p.ej. coches) comparten


ciertas características: sus atributos (tamaño, peso, color, potencia
del motor…) y el comportamiento que exhiben (aceleran, frenan,
curvan…).

OOP – Introducción: Java -3- © Fernando Berzal


Todo objeto tiene…

- Identidad (puede distinguirse de otros objetos)


- Estado (datos asociados a él)
- Comportamiento (puede hacer cosas)

Las diferentes instancias de cada clase difieren entre sí por los valores
de los datos que encapsulan (sus atributos).

Dos objetos con los mismos valores en sus atributos pueden ser
diferentes.

TODOS los objetos de una misma clase usan el mismo algoritmo como
respuesta a mensajes similares.

El algoritmo empleado como respuesta a un mensaje (esto es, el método


invocado) viene determinado por la clase del receptor.

Una clase es una descripción de un conjunto de objetos similares.

Al programar, definimos una clase para especificar cómo se comportan


y mantienen su estado los objetos de esa clase.

A partir de la definición de la clase, se crean tantos objetos de esa clase


como nos haga falta

OOP – Introducción: Java -4- © Fernando Berzal


Clases en Java

Cada clase en Java:

• Se define en un fichero independiente con extensión .java.

• Se carga en memoria cuando se necesita.

La máquina virtual Java determina en cada momento las clases


necesarias para la aplicación y las carga en memoria.

El programa puede ampliarse dinámicamente (sin tener que recompilar):


La aplicación no es un bloque monolítico de código.

Para definir una clase en Java se utiliza la palabra reservada class,


seguida del nombre de la clase (un identificador):

public class MiClase


{

}

NOTA: Es necesario que indiquemos el modificador de acceso public


para que podamos usar nuestra clase “desde el exterior”.

Los límites de la clase se marcan con llaves { … }

? Se debe sangrar el texto que aparece entre las llaves para


que resulte más fácil delimitar el ámbito de los distintos
elementos de nuestro programa. De esta forma se mejora
la legibilidad de nuestro programa.

OOP – Introducción: Java -5- © Fernando Berzal


Acerca del nombre de las clases

El nombre de una clase debe ser un identificador válido en Java.

Por convención, los identificadores que se les asignan a las clases en


Java comienzan con mayúscula.

Además, en Java, las clases públicas deben estar definidas en ficheros


con extensión .java cuyo nombre coincida exactamente con el
identificador asignado a la clase (¡ojo con las mayúsculas y las
minúsculas, que en Java se consideran diferentes!)

Errores comunes

ß Cuando el nombre de la clase no coincide con el nombre del


fichero, el compilador nos da el siguiente error:

Public class MiClase must be defined


in a file called MiClase.java

donde MiClase es el nombre de nuestra clase.

ß Las llaves siempre deben ir en parejas: Si falta la llave de cierre }


el compilador da un error:

‘}’ expected

Lo mismo ocurre si se nos olvida abrir la llave ({):


‘{’ expected

? Es una buena costumbre cerrar inmediatamente una


llave en cuanto se introduce en el texto del programa.
Después se posiciona el cursor entre las dos llaves y se
completa el texto del programa.

OOP – Introducción: Java -6- © Fernando Berzal


Uso del compilador javac
Al compilar un programa con javac,
el compilador nos muestra la lista de errores que se han detectado.

Para cada error, el compilador nos ofrece los siguientes datos:


- El nombre del fichero donde está el error.
- La línea en la que se ha detectado el error.
- Un mensaje descriptivo del tipo de error (en inglés).
- Una reproducción de la línea donde se detectó el error.
- La posición exacta donde se detectó el error en la línea.

Ejemplos

Al compilar el fichero Error.java, cuyo contenido es


public class 2Error
{
}
el compilador nos da los siguientes errores:
Error.java:1: malformed floating point literal
public class 2Error
^
Error.java:4: '{' expected

^
2 errors
El primer error se produce porque el identificador de la clase no es
válido y el segundo error es consecuencia del anterior.

Si cambiamos el identificador de la clase por un identificador válido en


Java, se produce un error si el nombre de la clase con el nombre del
fichero:

Error.java:1: class Error3 is public,


should be declared in a file named Error3.java
public class Error3
^
1 error
OOP – Introducción: Java -7- © Fernando Berzal
El compilador también nos dará un error si se nos olvida el punto y
coma del final de una sentencia o de una declaración, tal como sucede
en el siguiente ejemplo:

public class Error


{
int x
}

En este caso, el error se detecta en la línea siguiente a la declaración de


la variable x:

Error.java:4: ';' expected


}
^
1 error

En la mayoría de los lenguajes de programación, Java incluido,


el compilador ignora los espacios y líneas en blanco
que introduzcamos en el texto del programa.

? Los espacios y líneas en blanco los usaremos nosotros


para mejorar la legibilidad del texto del programa.

Cuando el compilador nos da un error, debemos comprobar la línea en


la que se detecta el error para corregirlo. Si esa línea no contiene errores
sintácticos, entonces debemos analizar las líneas que la preceden en el
texto del programa.

OOP – Introducción: Java -8- © Fernando Berzal


Encapsulación de datos (variables) y operaciones (métodos)

Objeto = Identidad + Estado + Comportamiento

Identidad
La identidad de un objeto lo identifica unívocamente:
- Es independiente de su estado.
- No cambia durante la vida del objeto.

Estado
El estado de un objeto viene dado por los valores de sus atributos.
- Cada atributo toma un valor en un dominio concreto.
- El estado de un objeto evoluciona con el tiempo
- Los atributos de un objeto no deberían ser manipulables
directamente por el resto de objetos del sistema (ocultamiento de
información):
o Se protegen los datos de accesos indebidos.
o Se distingue entre interfaz e implementación.
o Se facilita el mantenimiento del sistema.

Interfaz vs. implementación


Los objetos se comunican a través de interfaces bien
definidas sin tener que conocer los detalles internos de
implementación de los demás objetos.

Ejemplo: Un coche se puede conducir…


- Sin saber exactamente de qué partes consta el
motor ni cómo funciona éste (implementación).
- Basta con saber manejar el volante,
el acelerador y el freno (interfaz).
OOP – Introducción: Java -9- © Fernando Berzal
Comportamiento
Los métodos que definen el comportamiento de un objeto:
- Agrupan las competencias del objeto (responsabilidades)
- Describen sus acciones y reacciones.

Las acciones realizadas por un objeto son consecuencia


directa de un estímulo externo (un mensaje enviado desde otro
objeto) y dependen del estado del objeto.

El interfaz de un objeto ha de establecer un contrato, un conjunto de


condiciones precisas que gobiernan las relaciones entre una clase
proveedora y sus clientes (diseño por contrato).

Estado y comportamiento están relacionados.

Ejemplo
Un avión no puede aterrizar (acción) si no está en vuelo (estado)

Representación gráfica de una clase (notación UML)


Una clase se representa con un rectángulo dividido en tres partes:
- El nombre de la clase
(identifica la clase de forma unívoca)
- Sus atributos
(datos asociados a los objetos de la clase)
- Sus operaciones
(comportamiento de los objetos de esa clase)
IMPORTANTE: Las clases se deben identificar con un nombre que, por
lo general, pertenecerá al vocabulario utilizado habitualmente al
hablar del problema que tratamos de resolver.
OOP – Introducción: Java - 10 - © Fernando Berzal
Representación de una clase:

public class Cuenta


{

}
Declaración en Java de una clase.

Representación de una clase con sus atributos:

public class Cuenta


{
private double balance; // Saldo
private double limit; // Límite

}
Las variables de instancia
sirven para especificar en Java los atributos de la clase.

Representación del tipo y de los valores por defecto de los atributos:

public class Cuenta


{
private double balance = 0;
private double limit;

}
NOTA: Aquí hemos decidido utilizar el tipo primitivo
double para representar cantidades de dinero. En un
programa en el que no se pudiesen permitir errores
de redondeo en los cálculos, deberíamos utilizar otro
tipo más adecuado (por ejemplo, BigDecimal).
OOP – Introducción: Java - 11 - © Fernando Berzal
Representación de las operaciones de una clase:

public class Cuenta


{
private double balance = 0;
private double limit;
public void ingresar (…) …
public void retirar (…) …
}
Los métodos implementan en Java las operaciones
características de los objetos de una clase concreta.

Especificación completa de la clase:

public class Cuenta


{
private double balance = 0;
private double limit;

public void ingresar (double cantidad)


{
balance = balance + cantidad;
}

public void retirar (double cantidad)


{
balance = balance – cantidad;
}
}
OOP – Introducción: Java - 12 - © Fernando Berzal
Clase de ejemplo

Representación gráfica en UML:

Definición en Java:
Fichero Motocicleta.java

public class Motocicleta


{
// Atributos (variables de instancia)
private String matricula; // Placa de matrícula
private String color; // Color de la pintura
private int velocidad; // Velocidad actual (km/h)
private boolean en_marcha; // ¿moto arrancada?

// Operaciones (métodos)
public void arrancar ()
{ … }
public void acelerar ()
{ … }
public void frenar ()
{ … }
public void girar (float angulo)
{ … }
}

OOP – Introducción: Java - 13 - © Fernando Berzal


Uso de objetos
El operador .

El operador . (punto) en Java


nos permite acceder a los distintos miembros de una clase:

objeto.miembro

Cuando tenemos un objeto de un tipo determinado y queremos acceder


a uno de sus miembros sólo tenemos que poner el identificador asociado
al objeto (esto es, el identificador de una de las variables de nuestro
programa) seguido por un punto y por el identificador que hace
referencia a un miembro concreto de la clase a la que pertenece el
objeto.

¿Cómo se comprueba el estado de un objeto?


Accediendo a las variables de instancia del objeto

objeto.atributo

Por ejemplo, cuenta.balance nos permitiría acceder


al valor numérico correspondiente al saldo de una cuenta,
siempre y cuando cuenta fuese una instancia de la clase Cuenta.

¿Cómo se le envía un mensaje a un objeto?


Invocando a uno de sus métodos.

objeto.método(lista de parámetros)

La llamada al método hace que el objeto realice la tarea


especificada en la implementación del método, tal como esté
definida en la definición de la clase a la que pertenece el objeto.

OOP – Introducción: Java - 14 - © Fernando Berzal


Ejemplos

cuenta.ingresar(150.00);

- Si cuenta es el identificador asociado a una variable de tipo


Cuenta, se invoca al método ingresar definido en la clase
Cuenta para depositar una cantidad de dinero en la cuenta.

- La implementación del método ingresar se encarga de actualizar


el saldo de la cuenta, sin que nosotros nos tengamos que
preocupar de cómo se realiza esta operación.

System.out.println(“Mensaje”);

- System es el nombre de una clase incluida en la biblioteca de


clases estándar de Java.

- System.out es un miembro de la clase System que hace


referencia al objeto que representa la salida estándar de una
aplicación Java.

- println() es un método definido en la clase a la que pertenece el


objeto System.out.

- La implementación del método println() se encarga de mostrar


el mensaje que le pasamos como parámetro y hace avanzar el
cursor hasta la siguiente línea (como si pulsásemos la tecla ↵).

- System.out.println() es una llamada a un método, el método


println() del objeto System.out

- La línea completa forma una sentencia (terminada con un punto y


coma) que delega en el método println() para que éste se
encargue de mostrar una línea en pantalla.

OOP – Introducción: Java - 15 - © Fernando Berzal


Creación de objetos
Antes de poder usar un objeto hemos de crearlo…
El operador new
El operador new nos permite crear objetos en Java.

Tipo identificador = new Tipo();

Si escribimos un programa como el siguiente:


public class Ingreso
{
public static void main (String args[])
{
Cuenta cuenta; // Error
cuenta.ingresar(100.00);
}
}
El compilador nos da el siguiente error:
Ingreso.java:7:
variable cuenta might not have been initialized
cuenta.ingresar(100.00);
^
Hemos declarado una variable que, inicialmente, no tiene ningún valor.
Antes de utilizarla, deberíamos haberla inicializado (con un objeto del
tipo adecuado):

Cuenta cuenta = new Cuenta();

Observaciones
- Se suele crear una clase aparte, que únicamente contenga un
método main, como punto de entrada de la aplicación.
- En la implementación del método main se crean los objetos que
sean necesarios y se les envían mensajes para indicarles lo que
deseamos que hagan.

OOP – Introducción: Java - 16 - © Fernando Berzal


Constructores

Cuando utilizamos el operador new acompañado del nombre de una


clase, se crea un objeto del tipo especificado (una instancia de la clase
cuyo nombre aparece al lado de new).

Al crear un objeto de una clase concreta, se invoca a un método especial


de esa clase, denominado constructor, que es el que se encarga de
inicializar el estado del objeto.

Constructor por defecto

Por defecto, Java crea automáticamente un constructor sin parámetros


para cualquier clase que definamos.

public class Cuenta


{
// Constante
public static final double LIMITE_NORMAL = 300.00;

// Variables de instancia
private double balance = 0;
private double limit = LIMITE_NORMAL;

// Métodos
...
}

Al crear un objeto de tipo Cuenta con new Cuenta(), se llama al


constructor por defecto de la clase Cuenta, con lo cual se crea un
objeto de tipo Cuenta cuyo estado inicial será el indicado en la
inicialización de las variables de instancia balance y limit.

OOP – Introducción: Java - 17 - © Fernando Berzal


Constructores definidos por el usuario

Los lenguajes de programación nos permiten definir constructores para


especificar cómo ha de inicializarse un objeto al crearlo.

El nombre del constructor ha de coincidir con el nombre de la clase.

Podemos definir un constructor


para inicializar las variables de instancia de una clase,
en vez de hacerlo en la propia declaración de las variables de instancia:

public class Cuenta


{
// Constante
public static final double LIMITE_NORMAL = 300.00;

// Variables de instancia
private double balance;
private double limit;

// Constructor sin parámetros


public Cuenta ()
{
this.balance = 0;
this.limit = LIMITE_NORMAL;
}

// Métodos
...
}

La palabra reservada this hace referencia al objeto


que realiza la operación cuya implementación especifica el método.

OOP – Introducción: Java - 18 - © Fernando Berzal


También podemos definir constructores con parámetros:

public class Cuenta


{
// Constante
public static final double LIMITE_NORMAL = 300.00;

// Variables de instancia
private double balance;
private double limit;

// Constructor con parámetros


public Cuenta (double limit)
{
this.balance = 0;
this.limit = limit;
}

// Métodos
...
}

Ahora, para crear un objeto de tipo Cuenta, hemos de especificar los


parámetros adecuados para su constructor:

Cuenta cuenta = new Cuenta(Cuenta.LIMITE_NORMAL);

O bien

Cuenta cuentaVIP = new Cuenta(6000.00);

La cuenta VIP tendrá un límite de 6000



  
 

En cuanto definimos un constructor, ya no podemos utilizar el


constructor por defecto de la clase (el constructor sin parámetros que
Java crea automáticamente si no especificamos ninguno).

OOP – Introducción: Java - 19 - © Fernando Berzal


Si sólo está definido el constructor anterior

public Cuenta (double limit)

al crear un objeto con

Cuenta cuenta = new Cuenta();

el compilador de Java nos da el siguiente error:

CuentaTest.java:5: cannot find symbol


symbol : constructor Cuenta()
location: class Cuenta
Cuenta cuenta = new Cuenta();
^
1 error

porque no existe ningún constructor


sin parámetros definido para la clase Cuenta.

Para facilitarnos la creación de objetos,


Java nos permite definir varios constructores para una misma clase
(siempre y cuando tengan parámetros diferentes).

De forma que podemos incluir los dos constructores


en la implementación de la clase Cuenta y escribir lo siguiente:

public class CuentaTest


{
public static void main (String args[])
{
Cuenta cuentaNormal = new Cuenta();
Cuenta cuentaVIP = new Cuenta(6000.00);

}
}

OOP – Introducción: Java - 20 - © Fernando Berzal


Referencias
Cualquier tipo que definamos en Java con una clase
es un tipo no primitivo.

Cuando declaramos una variable de un tipo primitivo en Java, estamos


reservando espacio en memoria para almacenar
un valor del tipo correspondiente.

Sin embargo,
cuando declaramos una variable de un tipo no primitivo en Java,
lo único que hacemos es reservar una zona en memoria
donde se almacenará una referencia a un objeto del tipo especificado
(y no el objeto en sí, de ahí la necesidad de utilizar el operador new).

Inicialización por defecto de los objetos en Java

Cuando se crea un objeto con el operador new, por defecto:


- Las variables de instancia de tipo numérico (byte, short,
int, long, float y double) se inicializan a 0.

- Las variables de instancia de tipo char se inicializan a ‘\0’.


- Las variables de instancia de tipo boolean se inicializan a false.
- Las variables de instancia de cualquier tipo no primitivo se
inicializan a null (una palabra reservada del lenguaje que indica
que la referencia no apunta a ninguna parte).

IMPORTANTE
Para acceder a un miembro de un objeto
(leer el valor de una variable de instancia o invocar un método)
hemos de tener una referencia a un objeto distinta de null

OOP – Introducción: Java - 21 - © Fernando Berzal


Uso de sentencias de asignación

Cuando usamos datos de tipos primitivos,


las sentencias de asignación copian valores:

// Intercambio de los valores de dos variables

int x = 100;
int y = 200;
int tmp;

tmp = y; // La variable temporal


// almacena el valor inicial de y

y = x; // Se almacena en y el valor de x (100)

x = tmp; // Se almacena en x
// el valor original de y (200)

Cuando usamos objetos (datos de tipos no primitivos),


las sentencias de asignación copian referencias:

Cuenta miCuenta = new Cuenta();


Cuenta tmp;

tmp = miCuenta; // Copia la referencia

tmp.ingresar(150); // Se hace un ingreso en


// ¡¡¡ miCuenta !!!

MUY IMPORTANTE

En una sentencia de asignación,


no se crea una copia del dato representado por un objeto
(salvo que trabajemos con tipos primitivos)

OOP – Introducción: Java - 22 - © Fernando Berzal


Relaciones entre clases:
Diagramas de clases UML
Las relaciones existentes entre las distintas clases
nos indican cómo se comunican los objetos de esas clases entre sí:

Los mensajes “navegan”


por las relaciones existentes entre las distintas clases.

Existen distintos tipos de relaciones:

- Asociación (conexión entre clases)

- Dependencia (relación de uso)

- Generalización/especialización (relaciones de herencia)

OOP – Introducción: Java - 23 - © Fernando Berzal


Asociación
Una asociación es una relación estructural
que describe una conexión entre objetos.

Gráficamente, se muestra como una línea continua


que une las clases relacionadas entre sí.

Navegación de las asociaciones

Aunque las asociaciones suelen ser bidireccionales (se pueden


recorrer en ambos sentidos), en ocasiones es deseable hacerlas
unidireccionales (restringir su navegación en un único sentido).

Gráficamente, cuando la asociación es unidireccional, la línea


termina en una punta de flecha que indica el sentido de la
asociación:

Asociación unidireccional

Asociación bidireccional
OOP – Introducción: Java - 24 - © Fernando Berzal
equivale a

class Cuenta
{
private Dinero balance;

public void ingresar (Dinero cantidad)


{
balance += cantidad;
}

public void retirar (Dinero cantidad)


{
balance -= cantidad;
}

public Dinero getSaldo ()


{
return balance;
}
}

Hemos supuesto que Dinero es un tipo de dato con el que se pueden


hacer operaciones aritméticas y hemos añadido un método adicional que
nos permite comprobar el saldo de una cuenta.
OOP – Introducción: Java - 25 - © Fernando Berzal
viene a ser lo mismo que

con la salvedad de
que el enlace bidireccional hemos de mantenerlo nosotros

public class Cuenta


{

private Cliente titular;

}

public class Cliente


{

private Cuenta cuenta[];

}

Un cliente puede tener varias cuentas, por lo que en la clase cliente


hemos de mantener un conjunto de cuentas (un vector en este caso).
OOP – Introducción: Java - 26 - © Fernando Berzal
Multiplicidad de las asociaciones
La multiplicidad de una asociación determina
cuántos objetos de cada tipo intervienen en la relación:

El número de instancias de una clase que se relacionan


con UNA instancia de la otra clase.

- Cada asociación tiene dos multiplicidades


(una para cada extremo de la relación).

- Para especificar la multiplicidad de una asociación hay que indicar la


multiplicidad mínima y la multiplicidad máxima (mínima..máxima)

Multiplicidad Significado
1 Uno y sólo uno
0..1 Cero o uno
N..M Desde N hasta M
* Cero o varios
0..* Cero o varios
1..* Uno o varios (al menos uno)

- Cuando la multiplicidad mínima es 0, la relación es opcional.

- Una multiplicidad mínima mayor o igual que 1 establece una


relación obligatoria.

OOP – Introducción: Java - 27 - © Fernando Berzal


dirige
Profesor Departamento
1 0..1

Todo departamento tiene un director.


Un profesor puede dirigir un departamento.

Todo profesor pertenece a un departamento.


A un departamento pueden pertenecer varios profesores.

Relación opcional Relación obligatoria


Un cliente puede o no Una cuenta ha de tener
ser titular de una cuenta un titular como mínimo

Relaciones involutivas
Cuando la misma clase aparece en los dos extremos de la asociación.

OOP – Introducción: Java - 28 - © Fernando Berzal


Agregación y composición
Casos particulares de asociaciones:
Relación entre un todo y sus partes

Gráficamente,
se muestran como asociaciones con un rombo en uno de los extremos.

Agregación
Las partes pueden formar parte de distintos agregados.

Composición
Agregación disjunta y estricta:
Las partes sólo existen asociadas al compuesto
(sólo se accede a ellas a través del compuesto)

OOP – Introducción: Java - 29 - © Fernando Berzal


Dependencia
Relación (más débil que una asociación) que muestra la relación entre
un cliente y el proveedor de un servicio usado por el cliente.

- Cliente es el objeto que solicita un servicio.

- Servidor es el objeto que provee el servicio solicitado.

Gráficamente, la dependencia se muestra como una línea discontinua


con una punta de flecha que apunta del cliente al proveedor.

Ejemplo
Resolución de una ecuación de segundo grado

− b ± b 2 − 4ac
x=
2a
Para resolver una ecuación de segundo grado hemos
de recurrir a la función sqrt de la clase Math
para calcular una raíz cuadrada.

NOTA:
La clase Math es una clase “degenerada” que no tiene
estado. Es, simplemente, una colección de funciones
de cálculo matemático.

OOP – Introducción: Java - 30 - © Fernando Berzal


Herencia (generalización y especialización)
La relación entre una superclase y sus subclases

Objetos de distintas clases pueden tener atributos similares y exhibir


comportamientos parecidos (p.ej. animales, mamíferos…).

public class Empleado


{
...
}

public class Profesor extends Empleado


{
...
}

public class PAS extends Empleado


{
...
}

OOP – Introducción: Java - 31 - © Fernando Berzal


La noción de clase está próxima a la de conjunto:

Generalización y especialización
expresan relaciones de inclusión entre conjuntos.

Instancias: coches ⊂ vehículos

- Todo coche es un vehículo.

- Algunos vehículos son coches.

Propiedades: propiedades(coches) ⊃ propiedades(vehículos)

- Un coche tiene todas las propiedades de un vehículo.

- Algunas propiedades del coche no las tienen todos los vehículos.

OOP – Introducción: Java - 32 - © Fernando Berzal


Jerarquías de clases

Las clases se organizan


en una estructura jerárquica formando una taxonomía.

- El comportamiento de una categoría más general


es aplicable a una categoría particular.

- Las subclases heredan características de las clases de las que se


derivan y añaden características específicas que las diferencian.

En el diagrama de clases,
los atributos, métodos y relaciones de una clase se muestran en el nivel
más alto de la jerarquía en el que son aplicables.

OOP – Introducción: Java - 33 - © Fernando Berzal


Visibilidad
de los miembros de una clase
Se pueden establecer distintos niveles de encapsulación
para los miembros de una clase (atributos y operaciones)
en función de desde dónde queremos que se pueda acceder a ellos:

Visibilidad Significado Java UML


Se puede acceder al
Pública miembro de la clase public +
desde cualquier lugar.
Sólo se puede acceder
al miembro de la clase
Protegida desde la propia clase o protected #
desde una clase que
herede de ella.
Sólo se puede acceder
Privada al miembro de la clase private -
desde la propia clase.

Para encapsular por completo el estado de un objeto,


todos sus atributos se declaran como variables de instancia privadas
(usando el modificador de acceso private).

A un objeto siempre se accede a través de sus métodos públicos


(su interfaz).

Para usar el objeto no es necesario conocer


qué algoritmos utilizan sus métodos
ni qué tipos de datos se emplean para mantener su estado
(su implementación).
OOP – Introducción: Java - 34 - © Fernando Berzal
Diseño incorrecto

public class Persona


{
public String nombre;
public Persona padre;
public Persona madre;
public ArrayList hijos = new ArrayList();
}

Uso correcto de la clase:

Persona juan = new Persona();


Persona carlos = new Persona();
Persona silvia = new Persona();

juan.nombre = “Juan”;
carlos.nombre = “Carlos”;
silvia.nombre = “Silvia”;

juan.padre = carlos;
juan.madre = silvia;
carlos.hijos.add(juan);
silvia.hijos.add(juan);

Uso incorrecto de la clase


(pese a ser válido tal como está implementada):

juan.padre = carlos;
juan.madre = carlos;
silvia.hijos.add(juan);
juan.hijos.add(juan);

OOP – Introducción: Java - 35 - © Fernando Berzal


Diseño correcto

import java.util.ArrayList;

public class Persona


{
// Variables de instancia privadas
private String nombre;
private Persona padre;
private Persona madre;
private ArrayList hijos = new ArrayList();

// Constructores públicos
public Persona (String nombre)
{
this.nombre = nombre;
}

public Persona
(String nombre, Persona padre, Persona madre)
{
this.nombre = nombre;
this.padre = padre;
this.madre = madre;

padre.addHijo(this);
madre.addHijo(this);
}

OOP – Introducción: Java - 36 - © Fernando Berzal


// Método privado

private void addHijo (Persona hijo)


{
hijos.add(hijo);
}

// Métodos públicos
// p.ej. Acceso a las variables de instancia

public void setNombre (String nombre)


{
this.nombre = nombre;
}

public String getNombre ()


{
return nombre;
}

}
Con esta implementación, desde el exterior de la clase
no se pueden modificar las relaciones existentes entre padres e hijos,
por lo que estas siempre se mantendrán correctamente
si implementamos bien la clase Persona.

Ejemplo
Persona carlos = new Persona(“Carlos”);
Persona silvia = new Persona(“Silvia”);
Persona juan = new Persona(“Juan”,carlos,silvia);

Operación permitida (a través de un método público):

juan.setNombre(“Antonio”); // Cambio de nombre

Operación no permitida (error de compilación):

addHijo(Persona) has private access in Persona


juan.addHijo(carlos);
^

OOP – Introducción: Java - 37 - © Fernando Berzal


UML
El Lenguaje Unificado de Modelado
Grady Booch, Jim Rumbaugh e Ivar Jacobson

El lenguaje UML es un estándar OMG diseñado para visualizar,


especificar, construir y documentar software orientado a objetos.

Un modelo es una simplificación de la realidad.

El modelado es esencial en la construcción de software para…


- Comunicar la estructura de un sistema complejo
- Especificar el comportamiento deseado del sistema
- Comprender mejor lo que estamos construyendo
- Descubrir oportunidades de simplificación y reutilización

OOP – Introducción: Java - 38 - © Fernando Berzal


Un modelo proporciona “los planos” de un sistema y puede ser más o
menos detallado, en función de los elementos que sean relevantes en
cada momento.

El modelo ha de capturar “lo esencial”.

Todo sistema puede describirse desde distintos puntos de vista:


- Modelos estructurales (organización del sistema)
- Modelos de comportamiento (dinámica del sistema)

UML estandariza 9 tipos de diagramas para representar gráficamente un


sistema desde distintos puntos de vista.

Ventaja principal de UML


Unifica distintas notaciones previas.
Rumbaugh
Booch Jacobson

Odell
Meyer

Shlaer-Mellor UML
Harel
Gamma et. al.

Embly Wirfs-Brock
Fusion

Inconvenientes de UML
- Falta de integración con otras técnicas
(p.ej. diseño de interfaces de usuario)
- UML es excesivamente complejo (y no está del todo libre de
ambigüedades): “el 80% de los problemas puede modelarse
usando alrededor del 20% de UML”
OOP – Introducción: Java - 39 - © Fernando Berzal
Diagramas de clases
Muestran un conjunto de clases y sus relaciones

Los diagramas de clases proporcionan


una perspectiva estática del sistema
(representan su diseño estructural).
Notación

Atributos
[visibilidad] nombre [multiplicidad] [: tipo [= valor_por_defecto]]

Operaciones
[visibilidad] nombre ([[in|out] parámetro : tipo [, …]])[:tipo_devuelto]

- Los corchetes indican partes opcionales.


- Visibilidad: privada (-), protegida (#) o pública (+)
- Multiplicidad entre corchetes (p.ej. [2], [0..2], [*], [3..*])
- Parámetros de entrada (in) o de salida (out).

OOP – Introducción: Java - 40 - © Fernando Berzal


Diagramas de objetos
Muestran un conjunto de objetos y sus relaciones
(una situación concreta en un momento determinado).

Los diagramas de objetos representan instantáneas de instancias


de los elementos que aparecen en los diagramas de clases

Un diagrama de objetos expresa la parte estática de una interacción.

Para ver los aspectos dinámicos de la interacción


se utilizan los diagramas de interacción
(diagramas de secuencia y diagramas de comunicación/colaboración)

NOTA:
Los identificadores subrayados indican que se trata de objetos.
OOP – Introducción: Java - 41 - © Fernando Berzal
Diagramas de interacción
Muestran una interacción concreta: un conjunto de objetos y sus
relaciones, junto con los mensajes que se envían entre ellos.

Diagramas de secuencia
Resaltan la ordenación temporal de los mensajes que se intercambian.

: WInP réstamos :Socio :Video : Préstamo


: Encargado

prestar(video, socio)
verificar situación socio

verificar situación video

registrar préstamo

entregar recibo

Diagramas de comunicación (UML 2.0)


= Diagramas de colaboración (UML 1.x)
Resaltan la organización estructural
de los objetosque intercambian mensajes.
:Socio

:Video

2: verificar situación socio

1: prestar(video, socio) 3: verificar situación video


:WInPréstamos

5: entregar recibo
: Encargado 4: registrar préstamo

:Préstamo

OOP – Introducción: Java - 42 - © Fernando Berzal


Los diagramas de secuencia y de comunicación son isomorfos:
- Un diagrama de secuencia se puede transformar mecánicamente
en un diagrama de comunicación.
- Un diagrama de comunicación se puede transformar
automáticamente en un diagrama de secuencia.

Diagramas de secuencia
Muestran la secuencia de mensajes entre objetos durante un escenario
concreto (paso de mensajes).
- En la parte superior aparecen los objetos que intervienen.
- La dimensión temporal se indica verticalmente
(el tiempo transcurre hacia abajo).
- Las líneas verticales indican el período de vida de cada objeto.
- El paso de mensajes se indica con flechas horizontales u oblicuas
(cando existe demora entre el envío y la atención del mensaje).
- La realización de una acción se indica con rectángulos sobre las
líneas de actividad del objeto que realiza la acción.

Diagramas de comunicación/colaboración
La distribución de los objetos en el diagrama permite observar
adecuadamente la interacción de un objeto con respecto de los demás

- La perspectiva estática del sistema viene dada por las relaciones


existentes entre los objetos (igual que en un diagrama de objetos).

- La vista dinámica de la interacción viene indicada por el envío de


mensajes a través de los enlaces existentes entre los objetos.

NOTA: Los mensajes se numeran para ilustrar


el orden en que se emiten.

OOP – Introducción: Java - 43 - © Fernando Berzal


Otros diagramas UML
para representar aspectos dinámicos del sistema

- Diagramas de casos de uso


(actores y casos de uso del sistema)

C aso de U so
Actor

Los diagramas de uso se suelen utilizar en el modelado


del sistema desde el punto de vista de sus usuarios para
representar las acciones que realiza cada tipo de usuario.

- Diagramas de estados
(estados y transiciones entre estados),

contratar
en el paro en ac tivo

perder em pleo

jubilarse
jubil arse

jub ilado

Los diagramas de estados son especialmente importantes


para describir el comportamiento de un sistema reactivo
(cuyo comportamiento está dirigido por eventos).

OOP – Introducción: Java - 44 - © Fernando Berzal


- Diagramas de actividades
(flujo de control en el sistema)

Customer Sales Stockroom

Request
service

Take order

Play
Fill order

Deliver order

Collect
order

Los diagramas de actividades muestran el orden


en el que se van realizando tareas dentro de un sistema
(el flujo de control de las actividades).

OOP – Introducción: Java - 45 - © Fernando Berzal


Diagramas UML
para representar aspectos físicos del sistema
- Diagramas de componentes
(componentes y dependencias entre ellos)
Organización lógica de la implementación de un sistema

- Diagramas de despliegue
(nodos de procesamiento y componentes)
Configuración del sistema en tiempo de ejecución

<<Cliente>> <<Servidor>>
Terminal Punto <<TCP/IP>>
Base de
de Venta Datos

<<RDSI>>
<<LAN>>

OOP – Introducción: Java - 46 - © Fernando Berzal


Referencias

Páginas web

http://www.uml.org/
Página oficial de UML, uno de los estándares promovidos por el OMG.

http://www.cetus-links.org/oo_uml.html
Colección de enlaces relacionados con UML.

http://www.agilemodeling.com/essays/umlDiagrams.htm
Información práctica acerca de todos los diagramas UML 2

http://www.ootips.org/
Ideas clave en programación orientada a objetos.

Libros

Martin Fowler: “UML Distilled:


A Brief Guide to the Standard Object Modeling Language”
3rd edition. Addison-Wesley, 2004. ISBN 0321193687

Grady Booch et al.:


“Object-Oriented Analysis and Design with Applications”
3rd edition. Addison-Wesley, 2004. ISBN 020189551X

Craig Larman: “Applying UML and Patterns: An Introduction to


Object-Oriented Analysis and Design and the Unified Process”
2nd edition. Prentice-Hall, 2001. ISBN 0130925691

Robert C. Martin:
“Agile Software Development: Principles, Patterns, and Practices”
Prentice-Hall, 2003. ISBN 0135974445

OOP – Introducción: Java - 47 - © Fernando Berzal


Programación orientada a objetos
Relación de ejercicios

1. Proponga tres ejemplos de objetos del mundo real:

• Para cada uno de ellos, determine la clase a la que pertenecen.

• Asóciele a cada clase un identificador descriptivo adecuado.

• Enumere varios atributos y operaciones para cada una de las clases.

• Represente gráficamente las clases utilizando la notación UML.

• A partir de los diagramas UML, escriba el código necesario para definir


las clases utilizando el lenguaje de programación Java.

2. Rellene los huecos en las siguientes afirmaciones:

a. Los objetos encapsulan ________ y _________.

b. Los objetos se comunican entre sí pasándose _______.

c. Para comunicarse con un objeto concreto, no es necesario conocer su


_______, basta con saber cuál es su ________.

d. Pueden existir varios tipos de relaciones entre clases: _______,


_______ y _______.

e. Los lenguajes de programación orientada a objetos utilizan relaciones de


_______ para derivar nuevas clases a partir de clases base.

f. _____ define una notación gráfica estándar para representar diseños


orientados a objetos.

g. Las clases se definen en Java en ficheros de texto con la extensión _____

h. El compilador de Java genera ficheros con extensión ______ al compilar


un fichero de código fuente escrito en Java.
3. Definir adecuadamente las clases en Java que se derivan de los siguientes
diagramas de clases UML:
Alumno
DNI
Nombre
Dirección
Beca

* se matricula en
1..* Calificación
Asignatura
Profesor
ID Grupo
impartida en enseña NRP
Nombre
ID Nombre
Créditos
1 1..* Tipo * 1..* Categoría
Carácter
Área 1
Curso
*
asignada a *
Día pertenece a dirige
Hora
* 1

Aula Departamento 1
ID ID
Capacidad Nombre
Nota: CLASES ASOCIACIÓN

Las clases asociación (como “se matricula en”) se emplean para indicar que la
asociación existente entre dos clases tiene atributos propios:

En realidad, las clases asociación de un diagrama de clases UML son clases


convencionales cuyo único papel consiste en relacionar objetos de otras clases (no
tienen comportamiento propio)

Ejemplo

La fecha del alquiler no es un atributo del cliente ni de la película,


es algo específico del hecho de alquilar la película.

class Cliente

class Pelicula

class Alquiler
{
private Cliente cliente;
private Pelicula peli;
private DateTime fecha;

public Alquiler
(Cliente cliente, Pelicula peli, DateTime fecha)
{
this.cliente = cliente;
this.peli = peli;
this.fecha = fecha;
}

}

También podría gustarte