Sunteți pe pagina 1din 15

Programación II

Tema I: Relaciones entre clases.


Conferencia 1
Título: Diseño orientado a objetos. Relaciones entre clases.

Objetivo(s):
Que los estudiantes sean capaces de:
1. Identificar las clases y las relaciones que se establecen entre ellas en un determinado problema.
2. Caracterizar la relación tiene-un y las formas en que se expresa la misma
(Agregación/Composición).
3. Definir clases haciendo uso de las relación tiene-un en aquellos problemas que haga falta su
utilización.
4. Describir la implementación en C++ de la relación tiene-un.

Sumario:
 Tipos de clases presentes en un problema (Estudio Independiente (EI))
 Relaciones entre clases.
o Relación es-un.
o Relación tiene-un.
 Formas en que se expresa la relación tiene-un
o Agregación / Composición.
 Diagrama de clases para la representación de la relación tiene-un
 Caso de estudio: Almacén de Piezas.
 Implementación de la relación tiene-un en C++.

Bibliografía
 Cómo programar en C/C++ .Harvey M., Deitel- P.Deitel
 How Programming in C++. Harvey M., Deitel- P.Deitel (Están publicadas las ediciones 5, 6, 7,8)
 Introducción a la programación orientada a objetos. T. Budd
 Programación Orientada a Objetos en C++. M. Katrib Mora
 The C++ Programming Language. B. Stroustrup (Están publicadas las ediciones 3,4)
 Data Structures and Program Design in C++, Robert L. Kruse-Alexander J.Ryba
 Aprendiendo UML en 24 horas. Joseph Schmuller
 El Lenguaje Unificado de Modelado. Manual de referencia. James Rumbaugh, Ivar Jacobson, Grandy
Booch
 Materiales publicados en la página de la asignatura en el Aula Virtual del Departamento de TLC
(http://10.30.3.3/uoclas)

 Presentación de la asignatura. Sistema de evaluación

Tema I – Relaciones entre clases.


Tema II – Elementos avanzados de programación.

Evaluaciones Actividad
Trabajos de Control Parcial 2
Trabajo de control extraclase 1

 Introducción al contenido de la conferencia


Programar orientado a objetos implica, entre otras cosas, aprender a descubrir las clases presentes en un
problema así como las relaciones que se establecen entre ellas. Esta información es recomendable recogerla
en un diagrama bien organizado, el cual podría servir como guía para utilizar con efectividad las clases
presentes en el mismo.

1
En el tiempo de vida de un software, ésta es la etapa más importante, pues todo el trabajo posterior de
implementación se basa en este diseño, por lo que tiempo que se invierta en su elaboración, es tiempo
invertido: en reusabilidad de software, claridad del código, ocultación de información entre otros.

Esta conferencia la dedicaremos al estudio de una parte de esta primera etapa, dando nuestros primeros pasos
en el diseño orientado a objeto.

Desarrollo
Una de las primeras decisiones que se debe tomar, al crear una aplicación orientada a objetos, es la selección
de clases. Las clases en la programación orientada a objetos pueden tener tipos diferentes de
responsabilidades y por ello no sorprende que haya diferentes variedades de clases atendiendo a su
funcionalidad.
Tipos de clases presentes en un problema (EI)
 Clases entidad: Son clases cuya responsabilidad principal es mantener información de datos o de estado de
un género o de otro. Las clases manejadoras de datos con frecuencia se reconocen como los sustantivos en la
descripción de un problema y generalmente son los bloques de construcción fundamentales de un diseño.
 Clases controladoras: encargadas de desarrollar la lógica del sistema.
 Clases de interfaz: Clases que tienen que ver con la presentación de la información en dispositivo de
entrada/salida. Debido a que el código para llevar a cabo dicha actividad a menudo es complejo, modificado con
frecuencia y muy independiente de los datos reales que se están mostrando, es buena práctica de
programación aislar el comportamiento de presentación.
Con frecuencia los datos de base son llamados el modelo, mientras que la clase que se exhibe es llamada vista.
Al separar el modelo de la vista, por lo general se simplifica mucho el diseño del modelo. Idealmente, el modelo
no debe requerir ni contener ninguna información acerca de la vista. Esto facilita la reutilización del código, ya
que el modelo puede usarse en aplicaciones diferentes. Aunque en ocasiones es inevitable la interacción entre
el modelo y la vista, una buena práctica es reducir esta interacción al mínimo posible.
 Clases auxiliares: Estas son las clases que guardan poca o ninguna información del estado por si misma,
pero que asisten en la ejecución de tareas complejas.
La clasificación especializada de las clases no es objetivo de esta asignatura, pero por su interés
recomendamos la lectura de los tipos. Identificaremos las clases asociadas a los objetos fundamentales que
aparecen en el problema y nos centraremos en la parte del diseño que establece las relaciones entre las clases.
Hasta el momento, todas las soluciones brindadas a los problemas discutidos en P1, solo han involucrado una
única clase y esto se debe, principalmente, a que hemos concentrado todas las responsabilidades presentes en
el problema ella. Después de esta conferencia, nos daremos cuenta, que en un grupo de esos problemas parte
de esas responsabilidades podían haber sido relegadas a otras clases, y en conjunto colaborar en la solución
del mismo.

En ese sentido, una primera parte, y muy importante, del diseño inicial es la de determinar las clases presentes
en nuestro problema así como sus responsabilidades. Noten que hacemos mención a un diseño inicial y no al
“diseño”. Esto se debe a que el mismo puede estar sujeto a modificaciones y refinamientos añadiéndosele
clases y responsabilidades a las ya existentes, hasta llegar a un “diseño” que modele lo mejor posible nuestro
problema.

Una vez establecidas estas clases y sus responsabilidades más importantes, es momento de pasar a otro
momento del diseño. En esta parte nos dedicaremos a describir las relaciones que existen entre estas clases.

Relaciones entre clases


Hay dos relaciones de importancia capital en esta segunda etapa del diseño orientado a objeto; estas son
conocidas coloquialmente como la relación es – un y la relación tiene – un (o es parte – de)

o Relación es – un
Esta relación, también conocida como generalización–especialización, se establece entre dos conceptos
cuando el primero es un ejemplar especializado del segundo. Por ejemplo, para los objetos A y B, si tiene
sentido el enunciado “A es un B”, se puede diseñar la clase CA como una clase derivada de CB.

2
Ejemplos:
Un Perro es – un Mamífero
Un Círculo es – una Figura

Sobre esta relación no profundizaremos en este instante. La misma será estudiada en conferencias dedicadas
al tema.

o Relación tiene-un
Esta relación, que también se puede expresar como es parte – de, se da, cuando alguno de los conceptos es
un componente del otro, pero cuando los dos no son, en sentido alguno, la misma cosa, sin importar cuan
abstracta sea la generalidad.

Ejemplo:
Motor es parte – de un Automóvil
Un Estudiante tiene – un conjunto de Notas

La relación tiene–un, describe datos que se deben mantener dentro de una clase.
De la misma manera que muchos programadores novatos en orientación a objetos, se sienten inseguros en
como reconocer las clases en la descripción de un problema, muchos también dudan, sobre cuando una clase
debe convertirse en derivada de otra o cuando es mas apropiado que forme parte de ella. Y es que aunque la
mayoría de las veces, la distinción es muy clara. Algunas veces la diferencia puede ser muy sutil o puede
depender de las circunstancias.

Formas en que se expresa la relación tiene-un


La relación tiene-un o es parte-de, cómo también se le suele llamar, no se presenta como tal, sino a través de
sus dos variantes, la composición y la agregación. En ese sentido podemos decir que, las relaciones de
agregación y composición no son relaciones independientes de la relación tiene – un, sino que definen a esta
última.
o Agregación / Composición
La clase compuesta, también llamada clase contenedora, posee en su definición objetos de la clase
componente.

La principal diferencia entre estas dos variantes es la forma en que se asocian o se integran los objetos de las
clases componentes con los objetos de las clases compuestas.
En el caso de la composición, los objetos de la clase componente son dependientes de la existencia de los
objetos de la clase compuesta, es decir se establece una relación fuerte entre ellos, que implica que el
tiempo de “vida” de un objeto de la clase componente esta limitado por la existencia del objeto compuesto y
además, la clase compuesta tiene la responsabilidad de la creación y destrucción de sus objetos
componentes.
En la agregación, la relación que se establece entre los objetos de las clases es débil. Es decir, la existencia
de los objetos de la clase componente es independiente de la existencia de los objetos de la clase
compuesta. Por lo que en este tipo de relación, el tiempo de “vida” de un objeto de la clase componente no
tiene porque estar limitado por el de la clase compuesta.
En nuestra vida cotidiana estamos rodeados de objetos en los que se evidencia de una forma u otra esta
relación por ejemplo:
 La relación que se establece entre un árbol y sus hojas.
Es evidente que entre estos dos elementos se establece una relación de composición, ya que si se destruye
el árbol también las hojas morirán.
 Una computadora
En este caso una computadora cuenta con un gabinete, un teclado, un ratón, un monitor, una unidad de CD-
DVD, etc… Nuestra computadora es un ejemplo de agregación ya que se conforma de una combinación de
diversos tipos de objetos cada uno independiente del otro.
 Una camisa y sus partes

3
Una camisa esta compuesta de cuerpo, cuello, mangas, botones, ojales y puños. En este caso eliminamos la
camisa y sus partes por si sola no tendrían mucho sentido por lo que le relación que se establece es de
composición.

EJERCICIO PARA REFLEXIONAR


Supongamos que tenemos la siguiente representación de la clase CPersona:

CPersona
- Edad: int
- Sexo: char
- Talla: float
-Conyugue: CPersona

……

¿Qué tipo de relación, Agregación o Composición, se establece entre una persona y su cónyuge?

Siempre que vayamos a establecer que tipo de relación existe entre dos clases presentes en un problema, no
se debe perder nunca de vista la situación que van a modelar, ya que en ocasiones podría ser un elemento de
gran importancia a la hora de escoger la relación y facilitar la implementación del problema.
Ejemplo: La relación que se establece entre un auto y su motor puede ser vista de dos formas en situaciones
diferentes:
1. Para modelar una empresa recuperadora de materia prima puede tener sentido tener un carro
independiente de su motor incluso un motor independiente en sus partes. Por lo que para una situación
como esta es más conveniente representar estas relaciones como agregaciones.
2. Para modelar a una comercializadora de carro tiene mas sentido ver el carro como un todo y no
desglosado por sus partes por lo que pudiera tener mas sentido representarlo en este caso como una
relación de composición.

Es por eso, que es importante, a la hora de hacer la selección de las relaciones que se establecen entre las
clases, hacerlo teniendo en cuenta el contexto del problema que van a modelar.

Uso del diagrama de clases en UML para la representación de la relación tiene – un

El diagrama clases es una herramienta muy usada en el mundo informático. Éste describe los tipos de clases
que hay en el sistema y las relaciones que existen entre ellos. Además nos permite mostrar los atributos y
métodos de una clase.

En la asignatura PI presentamos una manera gráfica de representar las clases, la cual fue tomada de la
representación que se realiza en un diagrama de clases que brinda el UML y dada por un rectángulo dividido
en tres secciones. En la primera sección se coloca el nombre de la clase, en la segunda los atributos y en la
tercera los métodos.

Nombre
Atributos
Métodos

Figura 1: Representación de una clase


Estas relaciones de tipo tiene – un se representan con una línea que enlaza a las dos clases involucradas en la
relación. En este tipo de relación, también es importante, la multiplicidad indicando la cantidad de objetos que
participan en la relación.

4
La siguiente figura muestra que existe una relación de tipo tiene – un entre CA y CB y se leería CA tiene una o
muchas CB. CA es la clase compuesta y CB es la clase componente

CA CB
1 1..*

Figura 2: Representación de la relación tiene – un

La multiplicidad en la asociación es especificada en cada uno de los extremos de la asociación. Esta declara el
número de objetos que pueden satisfacer el extremo de la asociación. Las notaciones más utilizadas son:

 0..1 significa cero o un objeto


 1 significa un objeto
 0..* ó * significa cero o más objetos
 1..* significa uno o muchos objetos
 1... número estero positivo significa que la cantidad de objetos esta en el intervalo

Pero, esta representación no está totalmente completa, pues no nos permite diferenciar cuando la relación
tiene-un es de agregación o de composición. Para ello se utiliza un rombo coloreado o sin colorear, en
dependencia de la relación que se quiera representar, que se coloca sobre la línea de relación en el extremo
más próximo a la clase compuesta.

Ejemplo:
Si la relación que se establece entre las clases CA y CB es de composición donde A tiene-un B, su
representación seria:

CA CB
1 1
Figura 3: Representación de la relación tiene – un Composición

El rombo se coloca sobre la línea de relación en el extremo más próximo a la clase compuesta.

Si la relación que se establece entre las clases CA y CB es de agregación donde A tiene-un B su representación
seria:

CA CB
1 1
Figura 4: Representación de la relación tiene – un Agregación

El rombo se coloca sobre la línea de relación en el extremo más próximo a la clase compuesta.

5
Pongamos ahora en práctica lo aprendido hasta el momento analizando un caso de estudio que utilizaremos
además como base para el desarrollo del contenido que queda por dar.
Caso de Estudio: Almacén de Piezas
En un almacén se recepciona diariamente, una cantidad no fija de piezas de diferentes tipos, para cada tipo de
pieza el almacén llena una ficha con la siguiente información:
 Nombre de la pieza
 Código de la pieza
 País de procedencia
 Cantidad en existencia
 Precio unitario de la pieza

Se desea que usted elabore un diagrama de clases que recoja toda la información necesaria para elaborar un
sistema que permita.

1. Obtener un listado de las piezas ordenado alfabéticamente por el código.


2. El nombre de la pieza de mayor precio unitario.
3. El valor total de las piezas procesadas.
4. Un listado con todas las piezas de un país dado.
5. Permitir visualizar los datos de una pieza, conocido su código.

Para modelar este problema podemos hacer uso de dos clases, las cuales están perfectamente identificadas en
el texto del mismo. Esta son la clase CAlmacén y la clase CPieza.
Una vez identificadas las clases, tratemos de determinar y delegar las responsabilidades pertenecientes a cada
clase.
Haciendo una selección de las responsabilidades que debe implementar cada clase, le corresponde a la clase
pieza las responsabilidades de mantener la información de todos los datos que maneja el almacén por cada
unidad y brindar métodos que permitan recuperar la misma en todo momento.
El diagrama para esta clase quedaría como sigue:

CPieza
- Nombre: string
- Codigo: string
- Pais: string
- Existencia: int
- PrecioU: float

+ Pieza(aNombre: string, aCodigo: string, aPais:


CAlmacen
string, aExistencia: int, aPrecioU: float )
+ GetNombre(): string
cantReal: int
+ GetCodigo(): string
cantMaximo: int
+ GetPais(): string
+ Almacen()int
+ GetExistencia():
+ Almacen(int
+ GetPrecioU(): float ctdadMax)
+ ~Almacen()
+ Adiciona(CPieza *pficha): bool
Figura 5: Diagrama
+ getPieza(int UML Clase
pos): CPieza*
Pieza
+ ListadoOrdenado(listado :CPieza*) :int
+ NombreMayor(): string
+ ValorTotal(): float
+ ListadoPorPais(pais: String, listado : CPieza*):int
- Ordena(): void
+ BuscaPosPieza(string codigo): int

Figura 6: UML Clase Almacen

En cambio al almacén le corresponde llevar el control del listado de piezas que el administra y a su vez
brindar los mecanismos para dar respuesta a la información que se pide el sistema suministre. El diagrama

6
pudiera quedar de la siguiente forma todo esta en dependencia de la variantes que se tomen para
implementar las distintas responsabilidades aquí les proponemos una.

Ahora falta ver, antes de comenzar a implementar, la relación que se establece entre estas dos clases. Por
supuesto, un almacén tiene un conjunto de piezas y las piezas forman parte de un almacén, la relación es clara.
La variante que se establece es la que puede traer dudas. En nuestro criterio, la variante que más se adecua a
este problema, es la composición, pues una pieza solo tiene sentido vista como parte del almacén y no como
una entidad independiente

CAlmacen CPieza
cantReal: int - Nombre: string
cantMaximo: int - Codigo: string
- Pais: string
+ Almacen() - Existencia: int
+ Almacen(int ctdadMax) 1..* - PrecioU: float
+ ~Almacen()
+ Adiciona(CPieza * pficha): bool 1 + Pieza(aNombre: string, aCodigo: String, aPais:
+ getPieza(int pos): CPieza* String, aExistencia: int, aPrecioU: float )
+ ListadoOrdenado(listado : CPieza*) :int + GetNombre(): string
+ NombreMayor(): String + GetCodigo(): string
+ ValorTotal(): float + GetPais(): string
+ ListadoPorPais(pais: string, listado : CPieza*):int + GetExistencia(): int
- Ordena(): void + GetPrecioU(): float
+ BuscaPosPieza(string codigo): int

Figura 7: UML Problema Almacén de Piezas

7
Implementación de la relación tiene un en C++

Primeras variantes de implementación


Antes de empezar a implementar el caso de estudio que nos ocupa, puntualicemos las 2 variantes que se
utilizan para la implementación de la relación tiene – un.
Supongamos las dos clases, CA y CB, y que entre ellas existe una relación de la forma CA tiene – un CB ó CB
es parte – de CA representado por el siguiente diagrama de clases. Noten que en el diagrama se establece que
CA tiene solo una instancia de CB.

CA CB

1 1

En general, para implementar esta relación analicemos las siguientes dos alternativas:

class CA class CA
{ {
private: private:
CB objetob; CB *objetobptr;
…… ……
}; };

En el primero de los casos, se establece una relación fuerte entre las clases ya que al crear un objeto de la
clase CA automáticamente se crea un objeto de la clase CB y al destruirse ésta, al mismo tiempo y de forma
automática, se destruye también la instancia de la clase CB. Como ven esta forma de implementar la relación
está estrechamente vinculada con el concepto de composición, por lo que podría ser una buena variante para
implementar la relación tiene – un en el caso de que esta sea una composición de objetos.
Para el segundo caso, la relación que se origina entre las clases es débil, debido a que la creación de una
instancia de la clase CA no implica la creación de un objeto de la clase CB, solo la capacidad de apuntar un
objeto de esta clase en algún momento. Esta forma de implementación está más vinculada al concepto de
agregación por lo que resulta una buena opción a tener en cuenta para implementar la relación tiene – un en
caso que esta sea una agregación de objetos.
Es bueno aclarar que, aunque en la mayoría de los casos se cumple lo anteriormente expuesto, no se puede
tomar como una generalidad. De hecho, en algunos casos resulta conveniente la utilización del segundo
ejemplo para implementar una relación de composición de objetos y para ello solo se debe tener presente que
es responsabilidad de la clase contenedora el crear y destruir los objetos contenidos. Más adelante, incluso
veremos que existen casos que es obligatorio implementar la relación de composición haciendo uso de
punteros a objetos para hacer posibles mecanismos como el polimorfismo.
Otras dos variantes semejantes a las anteriores resultan, si el diagrama de clases tomara la siguiente forma.
Noten que en este caso lo que varió fue la multiplicidad de la relación.

CA CB

1 1..*

8
El análisis hecho para el diagrama anterior es válido también para este. La diferencia en las implementaciones
de estos casos consiste en que ahora la clase CA debe tener la capacidad de guardar la información de una o
varias instancias de la clase CB.

class CA class CA
{ {
private: private:
CB objetob[maximo]; CB *objetobptr[maximo];
…… ……
}; };

Para lograrlo la clase CA presenta en el primer ejemplo un arreglo con una cantidad de objetos de la clase CB
igual a máximo. Por lo que ahora, al crear una instancia de la clase CA se crearán máximo objetos de la clase
CB.
Para el segundo ejemplo ocurre algo parecido, lo que en este caso al crearse un objeto de la clase CA, se
crearán máximo punteros a objetos de la clase CB.
Analicemos estos planteamientos considerando el ejemplo del almacén:
En el caso de estudio que nos ocupa podríamos optar por una de las dos variantes expuestas en el último
ejemplo de implementación por ser las que se ajustan a la multiplicidad de nuestro problema, inclinándonos
preferentemente por la primera de las variantes por adecuarse mejor a la relación de composición presente en
nuestro problema, como una primera aproximación
No obstante debemos hacerle un último ajuste para poder cumplir con el requerimiento de poder tener en el
almacén cualquier cantidad no fija de piezas. Para ello modifiquemos la declaración estática del arreglo de
objetos por una que nos permita asignarle su tamaño posteriormente.

class CA
{
private:
CB *objetobptr;
……
};

Sigamos analizando cómo se materializa la relación tiene-un en la declaración de una clase en C++
detalladamente, considerando las dos formas de expresión de la relación y usando otra variante. Seguimos con
las 2 clases, CA - CB, y que entre ellas existe una relación de la forma CA tiene – un CB (ó CB es parte – de
CA) representado por el siguiente diagrama de clases. Noten que en el diagrama se establece que CA tiene
solo una instancia de CB.

CA CB

1 1

Figura 8: Ejemplo de Composición uno a uno

9
En código quedaría considerando que estamos trabajando con objetos como CB *objetoDeTipoCB:

class CA
{
private:
CB *obj;
……
};

La composición se expresaría:

class CA CA::CA()
{
{
obj = new CB();
private:
}
CB *obj;
CA:: ~CA()
public:
{
CA();
delete obj;
~CA();
}
};

En este primer caso se establece una relación fuerte entre las dos clases, ya que al crear el objeto de la clase
CA automáticamente se crea un objeto de la clase CB y al destruirse, al mismo tiempo y de forma automática,
se destruye también la instancia de la clase CB.

La agregación sería:

class CA CA::CA()
{ {
private: // …
CB *obj; }
public: ~CA::CA()
CA(); {
~CA(); // …
}; }

Para este segundo caso, la relación que se origina entre las clases es débil, debido a que la creación de una
instancia de la clase Ca no implica la creación de un objeto de la clase CB, solo implica la capacidad de apuntar
un objeto de esta clase.

Para el caso de multiplicidad 1..*:

CA CB

1 1..*
10
Figura 9: Ejemplo de Composición uno a muchos
El análisis hecho para el diagrama anterior es válido también para este. La diferencia en las implementaciones
de estos casos consiste en que ahora la clase CA debe tener la capacidad de guardar la información de una o
varias instancias de la clase CB.
Esto se logra también declarando en la clase CA un arreglo con una cantidad maximo de objetos de la clase CB:
si hasta ahora hemos trabajado objetos como CB *objetoDeTipoCB, y los arreglos se han usado como <Tipo> *
array = new <Tipo>[maximo], entonces un arreglo con capacidad para maximo objetos CB sería: CB * * = new
CB*[maximo];
Este arreglo dinámico de punteros es una variante que brinda muchas facilidades de implementación, las cuales
iremos mencionando cuando aparezcan situaciones propicias.
Regresando a nuestro caso de estudio, utilizando la última variante de implementación vista
Un primer paso para darle respuesta a esta interrogante es comparar cual de los ejemplos vistos (Figura 8 ó 9)
se corresponde con nuestro problema teniendo en cuenta principalmente la multiplicidad para hacer nuestra
elección (uno a mucho). Seguidamente tendremos en cuenta el tipo de relación que se establece si es de
agregación o composición (composición) y ya tendremos nuestra variante de implementación.

class CAlmacen
{
private:
CPieza* *fichasTec; //Arreglo dinámico de punteros a objetos al que se le asignará memoria luego
//…...
};

Llevemos a cabo entonces la declaración en C++ de las clases modeladas en nuestro problema

//Declaración de la clase CPieza


class CPieza
{
private:
string nombre;
string codigo;
string pais;
int existencia;
float precioU;
public:
CPieza();
CPieza(String nombre = “”, string codigo=””,string pais=””, int existencia=0, float precioU=0.0);
string GetNombre();
string GetCodigo();
string GetPais();
int GetExistencia();
float GetPrecioU();
};

EP: Pensar que otros métodos pueden agregarse a la clase CPiezas que le proporcionen mayor
funcionalidad

11
//Declaración de la clase CAlmacen
class CAlmacen
{
private:
CPieza** fichasTec;
int maximo; //Atributo que indica capacidad máxima del arreglo después de asignársele memoria
int cantReal; //Cantidad real de piezas asignadas en el arreglo.
void Ordena(); //Procedimiento que permite ordenar las piezas alfabéticamente por su código.
public:
CAlmacen(); //Constructor de la clase reservara memoria inicialmente para 50 elementos
CAlmacen(int ctdadMax) //Constructor de la clase reservara memoria para la cantidad indicada
int GetCantReal(); //Retorna la cantidad real de piezas almacenadas
bool Adiciona(CPieza *pfichaTec); // Adiciona una nueva pieza al arreglo.
int getPieza(int pos); // Retorna una referencia a la pieza en la posición indicada
int BuscaPosPieza(string codigo); // Busca la pieza con código indicado y retorna su posición
// ó retorna el valor -1 si esta no aparece
~CAlmacen(); //Destructor de la clase que libera la memoria ocupada por el arreglo.

};
CAlmacen::CAlmacen()
{
maximo = 50;
cantReal = 0;
fichasTec = new CPieza *[maximo];
}

CAlmacen::CAlmacen(int ctdadMax)
{
maximo = cantidad;
cantReal = 0;
fichasTec = new CPieza *[ctdadMax];
}

CAlmacen::~CAlmacen()
{
for(int i = 0; i < cantReal; i++)
delete fichasTec[i];
delete [] fichasTec;
}

Conclusiones

La clase de hoy la hemos dedicado al estudio de una de las primeras fases de desarrollo de un software, que es
la obtención de un diagrama de clase que modele y describa las relaciones de las clases extraídas del problema
a resolver. Conocimos que existen dos tipos de relaciones entre las clases y profundizamos en el estudio de
una de ellas, la relación (comúnmente conocida) tiene – un de la que abordamos su forma de implementación
en el lenguaje C++. Estudiar la parte que se encuentra al final de la conferencia indicada como estudio
independiente.

12
Ejercicios propuestos

1. Para cada uno de los pares siguientes, diga si la relación es de tipo es-un o tiene-un:
Casa – techo
Conserje – empleado
Ratón digital – dispositivo de entrada
Menú – ventana
Conjunto – colección

2. Cierta Universidad desea un programa computacional que le ayude a administrar las calificaciones
finales de sus estudiantes. Para cada estudiante se guarda su matrícula, nombre, apellidos, semestre, la
cantidad de materias que cursa y por cada materia se guarda el nombre y una calificación final. La
universidad distingue tres tipos de estudiantes especiales: los candidatos a graduarse, los de licencia
especial, los de postgrado. En el caso de los primeros se debe guardar su fecha de graduación y el
semestre (se debe poner en –1 para identificar que se ha graduado), en el caso de los segundos se debe
guardar cuántas materias está cursando que no corresponden a su programa académico y el semestre en
que estuvo de licencia. En el último caso se guarda su lugar de trabajo y escuela de origen.

a. Identifique todas las clases presentes en este Texto


b. Mencione las relaciones que se establecen entre ellos (tiene-un o es-un)
c. Realice el UML de una clase manejadora de datos.
d. Realice el UML de una clase pozo de datos. En caso de que tenga relación con otra clase
realice la implementación de la misma justificando la variante que utilice.

3. Se desea realizar un programa para automatizar la administración de una biblioteca, la cuál se realiza
actualmente en forma manual mediante tarjetas. La biblioteca dispone de un conjunto de publicaciones las
cuales se clasifican en libros, revistas y artículos para el préstamo a sus usuarios.
La información de los libros que se quiere mantener es un # de identificación (6 cifras) único que no podrá
modificarse luego de creado, título, autor, editorial, tema, estado (el estado del libro puede ser: disponible,
prestado, o reservado). Se representará cada uno de estos estados con una constante entera.
Una vez creado un nuevo libro, sus datos no podrán ser modificados. Si en el momento de la creación no se
especifica el estado del libro, se supondrá disponible. Naturalmente, el estado puede cambiar más adelante.
La biblioteca dispone además de otros tipos de publicaciones como revistas y artículos. De cualquier
publicación interesa conservar los mismos datos que tenían los libros, salvo que:
• Tanto para las revistas como para los artículos, no tiene sentido hablar de una Editorial.
• En el caso de las revistas deberá registrarse además, el año y número de la misma, y no tendrá
sentido hablar de un Autor.
• De los artículos interesa agregar en cambio el árbitro.

a. Identifique todas las clases presentes en este Texto


b. Mencione las relaciones que se establecen entre ellos (tiene-un o es-un)
c. Realice el UML de una clase controladora

4. Un Banco desea modernizar la forma en que administra las cuentas de ahorros de sus
clientes. Para ello se le pide diseñar un diagrama de clases el cual será utilizado posteriormente por un
equipo de desarrolladores para elaborar dicho sistema.

El banco para facilitar su trabajo le suministra la siguiente información:

Por cada cuenta, el banco mantiene los siguientes datos:

 Número de la cuenta
 Cliente (nombre, edad, CI, sexo)
 Fecha de Apertura (día, mes, año)
 Saldo de la cuenta
 Interés Anual
 Últimos 20 movimientos realizados en la cuenta (Tipo de movimiento (ingreso o reintegro),
cantidad, Momento (dia, mes, año, hora, minuto, segundos))

13
El saldo de la cuenta no puede estar en números rojos (negativos) y cada año se abonarán los intereses en
base al saldo medio de la cuenta.

El banco deberá proporcionar las siguientes funcionalidades:


 Crear Cuentas
 Cerrar Cuentas
 Realizar Movimientos en las Cuentas.
 Imprimir información de las Cuentas.

Realice el diagrama donde se recoja todas las clases que considere presentes en el problema, sus
responsabilidades, así como las relaciones entre ellas.

Estudio independiente (muy importante)


Supongamos que tenemos el siguiente diagrama UML utilizado para modelar a un encendedor eléctrico

CEncendedor
CDiodo
voltaje: float
annoVencimiento: int 1 materialBarrera: String
tipo: String
1 + CDiodo(materialBarrera: String )
+ CEncendedor(voltaje:float, annoVencimiento:int,
tipo: String, materialBarrera: String)

//Declaración de la clase CEncendedor


class CEncendedor
{
private:
float voltaje;
int annoVencimiento;
String tipo;
CDiodo componente;
public:
CEncendedor(float pvolataje, int pannoVencimiento, String ptipo, String pmaterialBarrera);
};

Son necesarios e imprescindibles los constructores por defecto en C++???


En C++ se utiliza un mecanismo para inicializar aquellos objetos que son atributos de una clase como es el
caso del atributo componente declarado en la clase CEncendedor. Como es sabido por nosotros antes de
crearse una instancia de una clase el compilador reserva memoria para cada uno de los atributos declarador en
la misma, pero
¿Qué sucede si uno de los atributos es un objeto? ¿Con cuales valores se inicializa?
En el mejor de los casos el compilador lo crea e inicializa automáticamente utilizando para ello el constructor por
defecto que suministre la clase contenida (CDiodo en nuestro ejemplo). En caso de no existir este constructor y
en su lugar tengamos uno que se le suministre información para crear el objeto, se hace necesaria la utilización
este mecanismo.
¿Cómo utilizarlos?
Para ello analicemos la declaración e implementación del constructor de la clase CEncendedor. Observen que
este constructor suministra los datos necesarios para poder construir e inicializar el objeto componente.

//Declaración
CEncendedor(float pvolataje, int pannoVencimiento, String ptipo, string pmaterialBarrera);

//Implementación

14
CEncendedor::CEncendedor(float pvolataje, int pannoVencimiento, string ptipo, string
pmaterialBarrera):componente(pmaterialBarrera);
{
voltaje = pvoltaje;
annVencimiento = pannoVencimiento;
tipo = ptipo;
}

Los dos puntos en el encabezado de la implementación separa el inicializador del atributo de la lista de
parámetros. Los inicializadores de miembros definen los parámetros pasados a los constructores de los objetos
miembros. Es decir el parámetro pmaterialBarrera es pasado al constructor de la clase CDiodo para inicializar el
objeto. En caso de necesitar varios inicializadores por tener varios atributos, instancias de clases diferentes
estos son separados por comas.

15

S-ar putea să vă placă și