calificaciones - L.P.S.I. - Universidad Politécnica de Madrid

Anuncio
Universidad Politécnica de Madrid
Escuela Universitaria de Informática
Departamento de Lenguajes, Proyectos y Sistemas Informáticos
Asignatura PROGRAMACIÓN II
EXAMEN DE LA CONVOCATORIA DE JULIO
Plan: 92 / Curso: 2013-2014
Madrid a 4 de Julio de 2014
APELLIDOS: .................................. NOMBRE: .................................................
Nº DE MATRÍCULA: ........ DNI:................. GRUPO: .........................................
CALIFICACIONES
TEORÍA
PROB_1
PROB_2
TOTAL
CUESTIONES TEÓRICAS
Valoración: 3 puntos.
Pregunta correcta:....................................0'2 puntos.
Pregunta no contestada o incorrecta: .... -0'15 puntos
I.
PROGRAMACIÓN CONCURRENTE.
1. Dibuje el diagrama de estados de un proceso
Preparado
Ejecución
Bloqueado
2. ¿Cómo definiría una acción atómica de grano fino?
Aquélla que se implanta directamente por el Hardware en el que se ejecuta el programa
concurrente
Página 1 de 14
Programación II
Julio 2014
3. En un semáforo cuyo contador es estrictamente positivo, ¿Puede haber algún proceso
bloqueado? Justifique su respuesta
NO.
Cuando un proceso hace WAIT sobre un semáforo, si el contador es >0, éste se decrementa en 1 y
prosigue su ejecución.
Por el contrario un proceso que hace un SIGNAL sobre el semáforo, si hay procesos bloqueados,
libera a uno y no incrementa el contador, manteniéndose a cero.
4. Describa la semántica utilizada por PASCAL_FC cuando un proceso desde el monitor A, invoca
a un procedimiento de un monitor B y dentro de B ejecuta una operación DELAY.
Mantiene la exclusión mutua sobre el monitor A y libera la exclusión mutua sobre el monitor B.
5. Ponga un ejemplo de problema en el que el acceso a las variables compartidas se haga de
forma combinada, unas veces concurrente y otras con acceso exclusivo.
El problema de los Lectores/Escritores
II.
PROGRAMACIÓN ORIENTADA A OBJETOS.
6. Defina la sobrecarga de métodos y cuáles son sus restricciones
Definición de distintos métodos con el mismo nombre en la misma clase o en clases diferentes.
En clases distintas no hay restricciones.
En la misma clase ha de variar en el número de parámetros, o teniendo el mismo número de
parámetros en los tipos de los parámetros dos a dos respectivamente
7. ¿Cuándo se ejecuta el método constructor de una clase?.
Cuando se crea un objeto de esa clase (estática o dinámicamente)
Página 2 de 14
Programación II
Julio 2014
8. ¿Tiene sentido en la implantación de una clase cA, escribir el código SELF.MetodoA, cuando
MetodoA es un método diferido de la clase cA? Razone su respuesta.
SI porque el método puede estar redefinido en una clase derivada, y cuando el objeto de la clase
derivada ejecute dicho código, SELF se referirá al objeto de la clase derivada y se ejecutará el
método A tal como esté definido en esa clase.
9. ¿Cuáles son las características de la relación de asociación entre clases?
Temporalidad: duradera, más que uso menos que composición.
Versatilidad: limitada, menos que el uso más que la composición.
Visibilidad: pública.
10. Atendiendo al gráfico de la figura, codifique en PIIPOO los atributos y constructores de las
clases necesarios para la implantación de las mismas.
CLASS INTERFACE cA;
PUBLIC METHODS
CONSTRUCTOR cA;
END CLASS INTERFACE cA;
cA
composición
composición
cB
cC
Asociación
CLASS INTERFACE cB;
PUBLIC METHODS
CONSTRUCTOR cB (pC: ^cC);
END CLASS INTERFACE cB;
CLASS IMPLEMENTATION cA;
ATTRIBUTES
mpC:^cC;
mpB: ^cB;
METHODS DEFINITION
CONSTRUCTOR cA;
BEGIN
NEW (mpC, cC);
NEW (mpB, cB(mpC)
END;
END CLASS IMPLEMENTATION cA;
CLASS IMPLEMENTATION cB;
ATTRIBUTES
mpC:^cC;
METHODS DEFINITION
CONSTRUCTOR cB (pC: ^cC);
BEGIN
mpC:=pC;
END;
END CLASS IMPLEMENTATION cB;
Página 3 de 14
Programación II
III.
Julio 2014
PROGRAMACIÓN FUNCIONAL.
11. Describa las funciones y operadores polimórficos que proporciona el lenguaje CAML, y defina
sus tipos
= y <>:
fst:
snd:
::
‘a * ‘a -> bool
‘a * ‘b -> ‘a
‘a * ‘b -> ‘b
‘a * ‘a list -> ‘a list
if then else:
hd:
tl:
bool* ‘a * ‘a -> ‘a
‘a list -> ‘a
‘a list -> ‘a list
12. ¿En qué consiste la evaluación perezosa de una expresión?
La evaluación de una subexpresión depende de la necesidad de su evaluación durante la ejecución
del programa.
13. Defina la transparencia referencial
El valor de una expresión compuesta depende únicamente de sus componentes y de nada más.
(no de la historia del programa en ejecución o de otros componentes que no estén inmersos en la
expresión).
14. ¿Son válidos los siguientes patrones? Justifique su respuestas para aquellos patrones
considerados inválidos.
a. _:: x :: [y] :: [ [( _,a,`b`)] ]
b. _ :: x :: (a,b) :: [(c,d,e)]
c. (x<0,y)
d. [snd(x,2);y]
a. SI
b. NO, porque los elementos de la lista deben ser del mismo tipo, y (a,b) es una tupla de 2
elementos y (c,d,e) es una tupla de 3 elementos.
c. NO, no se puede poner una expresión condicional (x<0) en un patrón.
d. NO, no se puede poner una expresión (snd(x,2)) en un patrón.
15. ¿Cuáles de los siguientes tipos son válidos?. Justifique su respuesta para aquellos tipos
considerados inválidos.
a. char*int -> char list
b. [float] * int -> float
c. _ * _ -> bool
d. int * float -> true
a. Válido
b. Inválido: el primer elemento de la tupla quiere representar una lista de float, y el tipo es float list
c. Inválido: un comodín _ NO puede formar parte de un tipo
d. Inválido: la constante lógica true NO puede formar parte de un tipo
Página 4 de 14
Programación II
Julio 2014
Universidad Politécnica de Madrid
Escuela Universitaria de Informática
Departamento de Lenguajes, Proyectos y Sistemas Informáticos
Asignatura PROGRAMACIÓN II
ENUNCIADOS DE LOS PROBLEMAS DEL
EXAMEN DE LA CONVOCATORIA DE JULIO
Plan: 92 / Curso: 2013-2014
Madrid a 4 de Julio de 2014
Fechas de Publicación de Notas y de Revisión de Exámenes
Publicación de Notas: Lunes 7 de Julio de 2014
Revisión de Examen y Prácticas: Viernes 11 de Julio de 2014 en horario que
será publicado en el tablón de la Asignatura a la publicación de las notas
Puede consultar sus notas en: www.lpsi.eui.upm.es/webprog2/Notas.htm
PROBLEMA 1: PROGRAMACIÓN CONCURRENTE
Puntuación: 2'5 puntos
Una fábrica de un cierto producto está formada por NumMaquinas máquinas que producen NumTiposPiezas
tipos de piezas, y por NumRobots robots de montaje que se encargan de ensamblar las piezas en el
producto final. Los tipos de piezas se identifican mediante un valor entero comprendido entre 1 y
NumTiposPiezas.
Cada máquina está controlada por un proceso que tiene la siguiente estructura de operaciones ya
implantadas en el sistema de control de la fábrica y que, por tanto, no pueden ser modificadas:
PROCESS TYPE TMaquina (IdMaquina: INTEGER; TipoPieza : INTEGER);
BEGIN
REPEAT
FabricarPieza(IdMaquina, TipoPieza);
AlmacenarPieza(IdMaquina, TipoPieza)
FOREVER
END;
Las máquinas fabrican repetidamente una pieza del mismo tipo. Una vez fabricada la pieza, se deposita en
un almacén de piezas común para todas las máquinas. El almacén de piezas puede albergar un máximo de
MaxPiezas piezas de cada tipo.
Por su parte, cada robot de montaje se controla mediante un proceso en el que se ejecutan las siguientes
operaciones inalterables ya definidas en el sistema de control de la fábrica:
PROCESS TYPE TRobot (IdRobot : INTEGER);
VAR
TipoPieza : INTEGER;
BEGIN
REPEAT
FOR TipoPieza := 1 TO NumTiposPiezas DO
BEGIN
RecogerPieza(IdRobot, TipoPieza);
MontarPieza(IdRobot, TipoPieza)
END
FOREVER
END;
Página 5 de 14
Programación II
Julio 2014
Los robots montan repetidamente productos, para lo cual montan las piezas en el producto en un orden
determinado. Para montar cada pieza, primero se realiza una operación de recogida de la pieza del almacén
de piezas, y después se monta la pieza en el producto.
Se pide añadir a los procesos de control de las máquinas y los robots todo el código necesario para
garantizar que se cumplan los siguientes requisitos:
- Las máquinas pueden fabricar piezas y los robots pueden montar piezas en el producto sin sufrir
ninguna interferencia por parte del resto de procesos.
- Las máquinas no pueden almacenar una pieza de un cierto tipo si el almacén se encuentra lleno de
piezas de ese tipo.
- Los robots no pueden recoger del almacén una pieza de un cierto tipo si no hay ninguna disponible
de ese tipo.
- Cualquier número de máquinas puede almacenar concurrentemente piezas de distinto tipo en el
almacén de piezas. Sin embargo, dos máquinas nunca pueden almacenar simultáneamente piezas del
mismo tipo.
-
Los robots de montaje siempre deben acceder al almacén de piezas bajo exclusión mutua entre sí.
- Una máquina puede almacenar una pieza y un robot puede recoger otra de tipo distinto
concurrentemente. Si las piezas son del mismo tipo, el almacenamiento y la recogida debe hacerse
bajo exclusión mutua.
- En ausencia de competencia, ni las máquinas ni los robots deben esperar para acceder al almacén
de piezas.
Para cumplir los anteriores requisitos, los ingenieros de la fábrica han decidido seguir la siguiente política:
- Una máquina sólo puede almacenar una pieza de un cierto tipo si el almacén puede albergar
piezas de ese tipo, no hay ninguna otra máquina almacenando una pieza de ese tipo y no hay ningún
robot recogiendo una pieza de ese tipo. En caso contrario, la máquina debe esperar para poder
almacenar la pieza.
- Un robot sólo puede recoger una pieza de un cierto tipo si hay piezas de ese tipo en el almacén, no
hay ninguna máquina almacenando una pieza de ese tipo y no hay ningún robot recogiendo una pieza
de cualquier tipo. En otro caso, el robot debe esperar para poder recoger la pieza.
- Cuando una máquina termina de almacenar una pieza de un cierto tipo, primero comprueba si
algún robot espera a recoger una pieza de ese tipo y puede recogerla, en cuyo caso lo libera. Si no
hubiera tal robot, comprueba si alguna otra máquina espera a almacenar una pieza de ese tipo y
puede almacenarla, en cuyo caso la libera.
- Cuando un robot termina de recoger una pieza de un cierto tipo, primero busca algún otro robot
que espere a recoger una pieza de cualquier tipo y pueda recogerla, en cuyo caso lo libera. Esta
búsqueda se debe realizar de menor a mayor tipo de pieza. Además, después comprueba si alguna
máquina espera a almacenar una pieza del mismo tipo que la pieza que se ha terminado de recoger y,
si puede almacenarla, también la libera.
Página 6 de 14
Programación II
Julio 2014
(* ************************************************************************ *)
MONITOR Almacen;
EXPORT
InicioAlmacenar, FinAlmacenar, InicioRecoger, FinRecoger;
VAR
NumPiezas : ARRAY [1..NumTiposPiezas] OF INTEGER;
Almacenando : ARRAY [1..NumTiposPiezas] OF BOOLEAN;
Recogiendo : BOOLEAN;
TipoPiezaRecogida : INTEGER;
ColaAlmacenar, ColaRecoger : ARRAY [1..NumTiposPiezas] OF CONDITION;
i : INTEGER;
(* ------------------------------------------------------------------------ *)
FUNCTION SePuedeAlmacenar (TipoPieza : INTEGER) : BOOLEAN;
BEGIN
SePuedeAlmacenar := (NumPiezas[TipoPieza] < MaxPiezas) AND
NOT Almacenando[TipoPieza] AND
NOT (Recogiendo AND (TipoPieza = TipoPiezaRecogida))
END;
(* ------------------------------------------------------------------------ *)
FUNCTION SePuedeRecoger (TipoPieza : INTEGER) : BOOLEAN;
BEGIN
SePuedeRecoger := (NumPiezas[TipoPieza] > 0) AND
NOT Almacenando[TipoPieza] AND
NOT Recogiendo
END;
(* ------------------------------------------------------------------------ *)
PROCEDURE InicioAlmacenar (TipoPieza : INTEGER);
BEGIN
(* Esperar a poder almacenar *)
IF NOT SePuedeAlmacenar(TipoPieza) THEN
DELAY(ColaAlmacenar[TipoPieza]);
(* Comenzar a almacenar *)
Almacenando[TipoPieza] := TRUE
END;
(* ------------------------------------------------------------------------ *)
PROCEDURE FinAlmacenar (TipoPieza : INTEGER);
BEGIN
(* Terminar de almacenar *)
Almacenando[TipoPieza] := FALSE;
NumPiezas[TipoPieza] := NumPiezas[TipoPieza] + 1;
(* Comprobar si un robot puede recoger una pieza del mismo tipo *)
IF NOT EMPTY(ColaRecoger[TipoPieza]) AND SePuedeRecoger(TipoPieza) THEN
RESUME(ColaRecoger[TipoPieza])
(* Comprobar si otra maquina puede almacenar una pieza del mismo tipo *)
ELSE
IF NOT EMPTY(ColaAlmacenar[TipoPieza]) AND SePuedeAlmacenar(TipoPieza) THEN
RESUME(ColaAlmacenar[TipoPieza])
END;
Página 7 de 14
Programación II
Julio 2014
(* ------------------------------------------------------------------------ *)
PROCEDURE InicioRecoger (TipoPieza : INTEGER);
BEGIN
(* Esperar a poder recoger *)
IF NOT SePuedeRecoger(TipoPieza) THEN
DELAY(ColaRecoger[TipoPieza]);
(* Comenzar a recoger *)
Recogiendo := TRUE;
TipoPiezaRecogida := TipoPieza
END;
(* ------------------------------------------------------------------------ *)
PROCEDURE FinRecoger;
VAR
TipoPieza, i : INTEGER;
BEGIN
(* Terminar de recoger *)
Recogiendo := FALSE;
NumPiezas[TipoPiezaRecogida] := NumPiezas[TipoPiezaRecogida] - 1;
(* Guardar el tipo de la pieza recogida por este robot *)
TipoPieza := TipoPiezaRecogida;
(* Buscar otro robot que pueda recoger una pieza de cualquier tipo *)
i := 1;
WHILE (i < NumTiposPiezas) AND
(EMPTY(ColaRecoger[i]) OR NOT SePuedeRecoger(i)) DO
i := i + 1;
IF NOT EMPTY(ColaRecoger[i]) AND SePuedeRecoger(i) THEN
RESUME(ColaRecoger[i]);
(*
(*
(*
IF
Comprobar si una maquina puede almacenar una pieza del mismo tipo *)
que la pieza recogida por este robot, y de distinto tipo que la *)
pieza del robot liberado (si lo hubiera) *)
NOT EMPTY(ColaAlmacenar[TipoPieza]) AND SePuedeAlmacenar(TipoPieza) THEN
RESUME(ColaAlmacenar[TipoPieza])
END;
(* ------------------------------------------------------------------------ *)
BEGIN
FOR i := 1 TO NumTiposPiezas DO
BEGIN
Almacenando[i] := FALSE;
Recogiendo := FALSE;
NumPiezas[i] := 0
END
END;
Página 8 de 14
Programación II
Julio 2014
(* ************************************************************************ *)
PROCESS TYPE TMaquina (IdMaquina: INTEGER; TipoPieza : INTEGER);
BEGIN
REPEAT
(* Fabricar una pieza *)
FabricarPieza(IdMaquina, TipoPieza);
(* Almacenar la pieza *)
Almacen.InicioAlmacenar(TipoPieza);
AlmacenarPieza(IdMaquina, TipoPieza);
Almacen.FinAlmacenar(TipoPieza)
FOREVER
END;
(* ************************************************************************ *)
PROCESS TYPE TRobot (IdRobot : INTEGER);
VAR
TipoPieza : INTEGER;
IdMaquina : ARRAY [1..NumTiposPiezas] OF INTEGER;
BEGIN
REPEAT
FOR TipoPieza := 1 TO NumTiposPiezas DO
BEGIN
(* Recoger una pieza *)
Almacen.InicioRecoger(TipoPieza);
RecogerPieza(IdRobot, TipoPieza);
Almacen.FinRecoger;
(* Montar la pieza *)
MontarPieza(IdRobot, TipoPieza)
END
FOREVER
END;
Página 9 de 14
Programación II
Julio 2014
PROBLEMA 2: PROGRAMACIÓN ORIENTADA A OBJETOS
Puntuación: 2'5 puntos
En una gran aplicación se precisa de una gestión exhaustiva de fechas.
Atendiendo a los requisitos se ha observado que, en una gran parte de la aplicación, la operación
crítica es calcular la diferencia del número de días entre dos fechas. Por este motivo se propone
para la clase cFecha el atributo dias (de la clase INTEGER) que contempla el número de días de
una fecha transcurridos desde el nacimiento de Cristo. De esta manera se facilita la codificación de
dicha operación y se optimiza su ejecución mediante la resta de dos números enteros.
Por otro lado, en otra gran parte de la aplicación, la operación crítica es la presentación por
pantalla. Por este motivo se propone para la clase cFecha el atributo cadena (de la clase STRING)
que contempla las secuencia de caracteres con el formato habitual (dia/mes/año). De esta manera
se facilita la codificación de dicha operación y se optimiza su ejecución mediante la presentación de
una cadena ya formateada.
Por último, en algunos puntos de la aplicación, existe la necesidad de combinar la gestión de
fechas con los diseños de atributos presentados anteriormente. El diseño final responde a una
solución de compromiso mediante una jerarquía de herencia con dos especializaciones que
respondan a ambas propuestas anteriores.
cFecha
cFechaEntero
cFechaCadena
CLASS INTERFACE cFecha;
END CLASS INTERFACE cFecha;
CLASS INTERFACE cFechaEntero;
INHERITS FROM
cFecha;
END CLASS INTERFACE cFechaEntero;
CLASS IMPLEMENTATION cFechaEntero;
ATTRIBUTES
dias : INTEGER;
PRIVATE METHODS
FUNCTION toFechaCadena : ^cFechaCadena;
END CLASS IMPLEMENTATION cFechaEntero;
Página 10 de 14
Programación II
Julio 2014
CLASS INTERFACE cFechaCadena;
INHERITS FROM
cFecha;
END CLASS INTERFACE cFechaCadena;
CLASS IMPLEMENTATION cFechaCadena;
ATTRIBUTES
cadena : STRING
PRIVATE METHODS
FUNCTION toFechaEntero : ^cFechaEntero;
END CLASS IMPLEMENTATION cFechaCadena;
SE PIDE:
Incorporar el todo código necesario a la jerarquía de clases anterior para que cualquier fecha
responda a los siguientes métodos:
PROCEDURE presentar;
FUNCTION diferencia (pFecha : POLYMORPHIC ^cFecha) : INTEGER;
NOTA:
Los métodos privados anteriores (toFechaCadena y toFechaEntero) para la conversión de objetos
de una clase hija a la otra y viceversa se encuentran disponibles sin necesidad de su implantación.
SOLUCIÓN 1:
CLASS INTERFACE cFecha;
PUBLIC METHODS
DEFERRED PROCEDURE presentar;
DEFERRED FUNCTION diferencia (pFecha : POLYMORPHIC ^cFecha) : INTEGER;
DEFERRED FUNCTION getDias : INTEGER;
END CLASS INTERFACE cFecha;
(***************************************************************************)
CLASS INTERFACE cFechaEntero;
INHERITS FROM cFecha;
PUBLIC METHODS
REDEFINED PROCEDURE presentar;
REDEFINED FUNCTION diferencia (pFecha : POLYMORPHIC ^cFecha) : INTEGER;
REDEFINED FUNCTION getDias : INTEGER;
END CLASS INTERFACE cFechaEntero;
(*-------------------------------------------------------------------------*)
CLASS IMPLEMENTATION cFechaEntero;
ATTRIBUTES
dias : INTEGER;
PRIVATE METHODS
FUNCTION toFechaCadena : ^cFechaCadena;
Página 11 de 14
Programación II
METHODS DEFINITION
Julio 2014
PROCEDURE presentar;
BEGIN
SELF.toFechaCadena^.presentar
END;
FUNCTION diferencia (pFecha : POLYMORPHIC ^cFecha) : INTEGER;
BEGIN
diferencia := dias – pFecha^.getDias
END;
FUNCTION getDias : INTEGER;
BEGIN
getDias := dias
END;
END CLASS IMPLEMENTATION cFechaEntero;
(***************************************************************************)
CLASS INTERFACE cFechaCadena;
INHERITS FROM cFecha;
PUBLIC METHODS
REDEFINED PROCEDURE presentar;
REDEFINED FUNCTION diferencia (pFecha : POLYMORPHIC ^cFecha) : INTEGER;
REDEFINED FUNCTION getDias : INTEGER;
END CLASS INTERFACE cFechaCadena;
(*-------------------------------------------------------------------------*)
Página 12 de 14
Programación II
Julio 2014
CLASS IMPLEMENTATION cFechaCadena;
ATTRIBUTES
cadena : STRING;
PRIVATE METHODS
FUNCTION toFechaEntero : ^cFechaEntero;
METHODS DEFINITION
PROCEDURE presentar;
BEGIN
cadena.WRITELN
END;
FUNCTION diferencia (pFecha : POLYMORPHIC ^cFecha) : INTEGER;
BEGIN
diferencia := SELF.getDias – pFecha^.getDias
END;
FUNCTION getDias : INTEGER;
BEGIN
getDias := SELF.toFechaEntero^.getDias
END;
END CLASS IMPLEMENTATION cFechaCadena;
SOLUCIÓN 2:
CLASS INTERFACE cFecha;
PUBLIC METHODS
PROCEDURE presentar;
FUNCTION diferencia (pFecha : POLYMORPHIC ^cFecha) : INTEGER;
DEFERRED FUNCTION getDias : INTEGER;
DEFERRED FUNCTION getCadena : STRING;
END CLASS INTERFACE cFecha;
(*-------------------------------------------------------------------------*)
CLASS IMPLEMENTATION cFecha;
METHODS DEFINITION
PROCEDURE presentar;
BEGIN
SELF.getCadena.WRITELN
END;
FUNCTION diferencia (pFecha : POLYMORPHIC ^cFecha) : INTEGER;
BEGIN
diferencia := SELF.getDias – pFecha^.getDias
END;
END CLASS IMPLEMENTATION cFecha;
(***************************************************************************)
Página 13 de 14
Programación II
Julio 2014
CLASS INTERFACE cFechaEntero;
INHERITS FROM cFecha;
PUBLIC METHODS
REDEFINED FUNCTION getDias : INTEGER;
REDEFINED FUNCTION getCadena : STRING;
END CLASS INTERFACE cFechaEntero;
(*-------------------------------------------------------------------------*)
CLASS IMPLEMENTATION cFechaEntero;
ATTRIBUTES
dias : INTEGER;
PRIVATE METHODS
FUNCTION toFechaCadena : ^cFechaCadena;
METHODS DEFINITION
FUNCTION getDias : INTEGER;
BEGIN
getDias := dias
END;
FUNCTION getCadena : STRING;
BEGIN
getCadena := SELF.toFechaCadena^.getCadena
END;
END CLASS IMPLEMENTATION cFechaEntero;
(***************************************************************************)
CLASS INTERFACE cFechaCadena;
INHERITS FROM cFecha;
PUBLIC METHODS
REDEFINED FUNCTION getDias : INTEGER;
REDEFINED FUNCTION getCadena : STRING;
END CLASS INTERFACE cFechaCadena;
(*-------------------------------------------------------------------------*)
CLASS IMPLEMENTATION cFechaCadena;
ATTRIBUTES
cadena : STRING;
PRIVATE METHODS
FUNCTION toFechaEntero : ^cFechaEntero;
METHODS DEFINITION
FUNCTION getDias : INTEGER;
BEGIN
getDias := SELF.toFechaEntero^.getDias
END;
FUNCTION getCadena : STRING;
BEGIN
getCadena := cadena
END;
END CLASS IMPLEMENTATION cFechaCadena;
Página 14 de 14
Descargar