programacion con asignaciones
TRANSCRIPT
FACULTAD DE INGENIERÍAFACULTAD DE INGENIERÍA
E.A.P. INGENIERÍA DE SISTEMAS E INFORMÁTICAE.A.P. INGENIERÍA DE SISTEMAS E INFORMÁTICA
MANUAL DEL CURSO:MANUAL DEL CURSO:
Teoría de LenguajesTeoría de Lenguajes(Unidad II)(Unidad II)
Tema:
Conceptos y ConstructoresConceptos y Constructores
Dictado por:
DIANA CECILIA MUÑOZ CASANOVADIANA CECILIA MUÑOZ CASANOVA
M.S. en Ingeniería de Sistemas e Informática
CHIMBOTE – PERÚCHIMBOTE – PERÚ
20072007
CAPÍTULO I: PROGRAMACIÓN CON ASIGNACIONES
1.1 Concepto. 621.2 Características 631.3 Operadores de asignación 631.4 Bloques de asignación 641.5 Efecto de una asignación 641.6 Asignaciones de valores de verdad. 661.7 Lenguajes que utilizan la programación en base a asignaciones. 66
Asignación en RUBY 66 Asignación en C++ 70 Asignación en JSCRIPT. 71 Asignación en PHP 72
CAPÍTULO II: ACTIVACIÓN DE PROCEDIMIENTOS
2.1 Concepto 742.2 Declaración de procedimiento 762.3 Ventajas y desventajas de los procedimientos 772.4 Utilización de datos en los procedimientos 782.5 Métodos de pasos de parámetros 79
2.5.1. Invocación por valor 792.5.2. Invocación por referencia 79
2.6 Tiempo de vida animada de las activaciones 802.7 Estructura del bloque 80
2.7.1. Propósito de las estructuras de bloque 802.7.2. Procedimiento como parámetros 81
2.8 Disposición de tipo de dato asignable 812.9 Apuntadores y asignación dinámica de valores 82
2.9.1. Punteros 822.9.2. Variables estáticas 822.9.3. Variables dinámicas 832.9.4. Estructura de datos ligados. 832.9.5. Operaciones con punteros 83
CAPÍTULO III: ENCAPSULAMIENTO Y HERENCIA DE DATOS 3.1 Paradigma de la programación orientada a objetos 843.2 Componentes básicos de la POO. 85
3.2.1. Objetos 853.2.2. Clase 863.2.3. Mensaje 87
3.3 Manejo automático de memoria. 883.4 Características fundamentales de la POO 90
3.5 Encapsulamiento de datos 913.6 Herencia de datos 91
3.6.1. Tipos de herencia 933.7 Constructores para la construcción de programas 95
3.7.1. Procedimientos. 953.7.2. Módulos. 963.7.3. Clases. 97
3.8 Clases derivadas y ocultación de la información 973.8.1. Visibilidad de la información (ocultamiento). 97
CAPÍTULO IV: PROGRAMACIÓN FUNCIONAL
4.1 Concepto 984.2 El objetivo 984.3 Características propias de estos lenguajes 984.4 Categorías de lenguajes funcionales 99
Universidad Nacional del Santa Facultad de Ingeniería Manual de Teoría de lenguajes E. A. P Ingeniería de Sistemas e Informática Unidad II
CAPÍTULO I: PROGRAMACIÓN CON ASIGNACIONES
1.1 CONCEPTO.
Este tipo de programación se basa en los operadores característicos de cada
lenguaje de programación que son los operadores de asignación, que comúnmente
aparece con un signo igual (=). Cambia el valor de la variable que está a la
izquierda por un literal o el resultado de la expresión que se encuentra a la derecha.
La sintaxis usada para ello es:
<destino> = <origen>
Una asignación será correcta siempre que la anotación de tipo no haya enlazado la
variable a un tipo de datos determinado en la instrucción. En caso contrario, el
compilador intentará convertir <destino> al tipo de datos de <origen>. Si la
conversión nunca se puede realizar correctamente, el compilador genera un error.
Si la conversión se realiza correctamente para algunos valores, pero falla con
otros, el compilador genera una advertencia informando de que se puede producir
un error cuando se ejecuta el código.
A diferencia de lenguajes de programación descendientes de C, Pascal utiliza el
símbolo := para la asignación en vez de =. Si bien el segundo es más conciso, la
práctica ha demostrado que muchos usuarios utilizan el símbolo de igualdad para
comparar valores en lugar del comparador de C que es el símbolo ==. Esta sintaxis
conduce a muchos errores [bugs] difíciles de rastrear en código C. Dado que
Pascal no permite dentro de expresiones y utiliza sintaxis distinta para
asignaciones y comparaciones, no sufre estos errores.
Otra diferencia importante es que en Pascal, el tipo de una variable se fija en su
definición; la asignación a variables de valores de tipo incompatible no están
autorizadas (En C, en cambio, el compilador hace el mejor esfuerzo para dar una
interpretación a casi todo tipo de asignaciones). Esto previene errores comunes
donde variables son usadas incorrectamente porque el tipo es desconocido. Esto
también evita la necesidad de notación húngara, esto es prefijos que se añaden a
los nombres de las variables y que indican su tipo.
M.S. Diana Cecilia Muñoz Casanova - 62 -
Universidad Nacional del Santa Facultad de Ingeniería Manual de Teoría de lenguajes E. A. P Ingeniería de Sistemas e Informática Unidad II
1.2 CARACTERÍSTICAS
Las asignaciones son expresiones y responden el resultado
de evaluar el miembro de la derecha.
Las asignaciones pueden encadenarse, resultando que la
asignación del miembro derecho sea la respuesta de la asignación anterior.
Las asignaciones no copian datos, ligan nombres a
objetos. Siempre van al ámbito interno.
Una asignación es simplemente una instrucción mediante
la que se indica un valor a almacenar en un dato.
Se debe tener en cuenta que a una variable sólo se le
pueden asignar valores que correspondan a su tipo de dato, así, por ejemplo,
no se le puede asignar un número flotante a una variable entera.
Ejemplo: declaración de variables, términos y asignación en C++
Definidas las variables a y b, estas pueden usarse en la construcción de
términos y se les pueden asignar los valores representados por estos:
int a; /*Se declara la variable entera a*/
a=5; /*Se asigna a a el valor 5*/
a= 5.62 /*esta línea de código es un error*/
1.3 OPERADORES DE ASIGNACIÓN
Los operadores de asignación, son aquellos que nos permiten modificar el valor de
una variable, el operador de asignación básico es el 'es igual a' (=), que da el valor
que lo sigue a la variable que lo precede:
Veamos un ejemplo de una instrucción tonta, que en realidad no hace nada.
algo = algo;
La variable algo toma el valor de algo; todo queda como antes. Ahora aumentemos
el valor de la variable en 3 unidades.
algo = algo + 3;
Aquí la variable toma el valor que tenía mas 3 unidades. Existe una forma de
simplificar la notación anterior. Es la siguiente:
algo += 3; // equivalente a algo = algo + 3
M.S. Diana Cecilia Muñoz Casanova - 63 -
Universidad Nacional del Santa Facultad de Ingeniería Manual de Teoría de lenguajes E. A. P Ingeniería de Sistemas e Informática Unidad II
Se juntaron el operador de suma con el de asignación. Este atajo se puede realizar
para otras operaciones además de la suma.
Tabla Nº 1: Operadores de asignación
Operadores de asignación
Operación Operador Utilización Operación equivalente
Suma += A += B A = A + BResta -= A -= B A = A - BMultiplicación *= A *= B A = A * BDivisión /= A /= B A = A / BResto de división %= A %= B A = A % BDesplazamiento a la izquierda
<<= A <<= B A = A << B
Desplazamiento a la derecha >>= A >>= B A = A >> BDesplazamiento a la derecha sin signo
>>>= A >>>= B A = A >>> B
AND de bits &= A &= B A = A & BOR de bits |= A |= B A = A | BXOR de bits ^= A ^= B A = A ^ B
1.4 BLOQUES DE ASIGNACIÓN
Un bloque de asignación se compone de asignaciones, que se encuentran dentro
de una asignación superior. De esta forma los bloques de asignación pueden estar
por ejemplo dentro de asignaciones de condiciones o dentro de bucles. También
todas las asignaciones que están dentro de un subprograma forman un bloque de
asignación.
1.5 EFECTO DE UNA ASIGNACIÓN
Una propiedad característica de cualquier asignación es que cambia un valor
almacenado en la maquina, Una asignación cambia el estado de la máquina, donde
el estado corresponde comparativamente a una fotografía de la memoria de la
máquina.
Una Maquina de acceso Aleatorio tiene:
M.S. Diana Cecilia Muñoz Casanova - 64 -
Universidad Nacional del Santa Facultad de Ingeniería Manual de Teoría de lenguajes E. A. P Ingeniería de Sistemas e Informática Unidad II
Una Memoria: Consiste en la secuencia de localidades 0, 1, 2,… cada una
capaz de almacenar un entero a la vez. La dirección de la maquina es el
numero de una localidad en memoria, el entero almacenado en una localidad
se identifica como el contenido de una localidad.
El programa: Consiste en una secuencia de instrucciones. El conjunto de
instrucciones tiene instrucciones para asignaciones, entrada y salida y flujo de
control. Las asignaciones examinadas individualmente tienen la forma de :
< expresión 1>:= <expresión 2>
Donde:
<expresión 1 > denota localidad de memoria .
<expresión 2 > denota un valor.
Archivo de Entrada: Es una secuencia de valores tomados de uno en uno
por instrucción de la forma read M[i], que obtiene el siguiente valor del
archivo de entrada y lo coloca en la localidad i.
Archivo de Salida: Es una secuencia de valores producidos uno a la vez
por instrucciones de la forma write M[i], que coloca el valor de la localidad i
entro del archivo de salida.
Gráfico Nº 1: Maquina de acceso Aleatorio
1.6 ASIGNACIONES DE VALORES DE VERDAD.
M.S. Diana Cecilia Muñoz Casanova - 65 -
read M[1]read M[2]M[1] := M[1]- M[2]If M[1] >=then goto 3M[1] := M[1] + M[2]Write M[1]Halt
Control
Memoria
Entrada
Salida
27 10
0 1 2 3
Universidad Nacional del Santa Facultad de Ingeniería Manual de Teoría de lenguajes E. A. P Ingeniería de Sistemas e Informática Unidad II
Es una función que asocia Verdadero o Falso a las variables proposicionales.
En este sistema una asignación se puede representar por alguna de las siguientes
maneras:
1. Dos lista de variables entre llaves, separadas por una barra vertical:
{a, b, c, z| f, g}
2. Una variable de asignación representada con una letra mayúscula.
3. Una variable .corregida. con una lista de asignaciones: A[b=V,d=F]
En el caso 1. La primera lista son las variables que tienen asociado el valor
verdadero, y la segunda las variables que tienen asociado el valor falso. Puede
haber variables repetidas. Si una variable aparece en las dos listas se considera que
su valor es verdadero.
En el caso 2. Se utiliza un nombre simbólico para representar una asignación. Este
nombre debe haber sido definido mediante un comando asignar. Como los
presentados en la anterior tabla.
En el caso 3.La asignación coincide con A salvo en los valores especificados entre
corchetes. Si se repiten variables se toma el último valor (el que aparece más a la
derecha)
1.7 LENGUAJES QUE UTILIZAN LA PROGRAMACIÓN EN BASE A
ASIGNACIONES.
ASIGNACIÓN EN RUBY
Hay dos formas básicas de asignación en Ruby. La primera asigna una
referencia de objeto a una variable o constante. Esta forma de asignación esta
integrada en el lenguaje.
instrument = "piano"
MIDDLE_A = 440
La segunda forma de asignación involucra un atributo de objeto o una
elemento de referencia en el lado izquierdo.
aSong.duration = 234
M.S. Diana Cecilia Muñoz Casanova - 66 -
Universidad Nacional del Santa Facultad de Ingeniería Manual de Teoría de lenguajes E. A. P Ingeniería de Sistemas e Informática Unidad II
instrument["ano"] = "ccolo"
Estas formas son especiales, porque están implementadas mediante llamadas a
métodos en el lado izquierdo, lo cual significa que las puede modificar. Ya
hemos visto como definir un atributo de objeto como modificable.
Simplemente definimos un nombre de método terminando en un signo de
igual. Este método recibe como parámetro el valor de la derecha.
class Song
def duration=(newDuration)
@duration = newDuration
end
end
No hay necesidad o razón para que estos métodos para establecer atributos
tengan que corresponder con variables de instancia internas, o que tenga que
existir un lector de atributos por cada modificador de atributos
class Amplifier
def volume=(newVolume)
self.leftChannel = self.rightChannel = newVolume
end
# ...
End
Asignación Paralela
Durante la primera semana en un curso de programación (ó el segundo
semestre si es una escuela oficial), tal vez tendría que escribir código para
intercambiar los valores en dos variables:
int a = 1;
int b = 2;
int temp;
temp = a;
M.S. Diana Cecilia Muñoz Casanova - 67 -
Universidad Nacional del Santa Facultad de Ingeniería Manual de Teoría de lenguajes E. A. P Ingeniería de Sistemas e Informática Unidad II
a = b;
b = temp;
Usted puede realizar esto de una manera mas limpia en Ruby:
a, b = b, a
Las asignaciones de Ruby son efectivamente realizadas en forma paralela,
así que los valores asignados no son afectados por la asignación en si
misma. Los valores en el lado derecho son evaluados en el orden en el cual
aparecen antes de realizar la asignación a las variables a la izquierda. Un
ejemplo algo artificial ilustrará esto. La segunda línea asigna a las
variables a, b, y c los valores de las expresiones x, x+=1, y x+=1,
respectivamente.
x = 0 » 0
a, b, c = x, (x += 1), (x += 1) » [0, 1, 2]
Cuando una asignación tiene más de un valor izquierdo, la expresión de
asignación regresa un arreglo de los valores derechos. Si una asignación
contiene mas valores izquierdos que derechos, los valores izquierdos
excedentes contendrán nil. Si una asignación múltiple contiene mas valores
derechos que izquierdos, los valores derechos sobrantes serán ignorados. A
partir de Ruby 1.6.2, si una asignación contiene un valor izquierdo y varios
derechos, los valores a la derecha serán convertidos en un arreglo y
asignados al valor izquierdo.
Usted puede colapsar o expandir los arreglos usando el operador de
asignación paralela de Ruby. Si el último valor izquierdo esta precedido
por un asterisco, todos los valores derechos sobrantes serán recolectados y
asignados a ese valor izquierdo como un arreglo. De manera similar, si el
último valor derecho es un arreglo, le puede preceder con un asterisco, lo
cual efectivamente expande dicho arreglo a los valores de sus elementos
constituyentes. (Esto no es necesario si el valor derecho es lo único que
hay del lado derecho en este caso será expandido por defecto.)
M.S. Diana Cecilia Muñoz Casanova - 68 -
Universidad Nacional del Santa Facultad de Ingeniería Manual de Teoría de lenguajes E. A. P Ingeniería de Sistemas e Informática Unidad II
a = [1, 2, 3, 4]
b, c = a » b == 1, c == 2
b, *c = a » b == 1, c == [2, 3, 4]
b, c = 99, a » b == 99, c == [1, 2, 3, 4]
b, *c = 99, a » b == 99, c == [[1, 2, 3, 4]]
b, c = 99, *a » b == 99, c == 1
b, *c = 99, *a » b == 99, c == [1, 2, 3, 4]
Asignaciones Anidadas
Las asignaciones paralelas tienen otra característica que vale la pena
mencionar. El lado izquierdo de la asignación puede contener una lista de
términos dentro de paréntesis. Ruby trata estos términos como si fuera una
declaración de asignaciones anidadas. Extrae los correspondientes valores
derechos, asignandolos a los términos en paréntesis, antes de continuar con
las asignaciones de mayor nivel.
b, (c, d), e = 1,2,3,4 » b == 1, c == 2, d == nil, e == 3
b, (c, d), e = [1,2,3,4] » b == 1, c == 2, d == nil, e == 3
b, (c, d), e = 1,[2,3],4 » b == 1, c == 2, d == 3, e == 4
b, (c, d), e = 1,[2,3,4],5 » b == 1, c == 2, d == 3, e == 5
b, (c,*d), e = 1,[2,3,4],5 » b == 1, c == 2, d == [3, 4], e == 5
Otras Formar de Asignación
En común con otros lenguages, Ruby posee el atajo sintáctico: a=a+2
puede ser escrito como a+=2.
La segunda forma es convertida internamente a la primera. Esto significa
que los operadores que haya definido en sus propias clases funciona de la
manera esperada.
class Bowdlerize
def initialize(aString)
@value = aString.gsub(/[aeiou]/, '*')
end
M.S. Diana Cecilia Muñoz Casanova - 69 -
Universidad Nacional del Santa Facultad de Ingeniería Manual de Teoría de lenguajes E. A. P Ingeniería de Sistemas e Informática Unidad II
def +(other)
Bowdlerize.new(self.to_s + other.to_s)
end
def to_s
@value
end
end
a = Bowdlerize.new("damn ") » d*mn
a += "shame" » d*mn sh*m*
ASIGNACIÓN EN C++
El comportamiento por defecto en C++ es copiar cada miembro del objeto
Es posible hacer sobrecarga del operador =
En este caso el programador determina lo que ocurrirá cuando se asigna un
objeto a otro
No se debe confundir la asignación con la inicialización (constructores de
copia)
Para realizar asignaciones se usa en C++ el operador =, operador que además
de realizar la asignación que se le solicita devuelve el valor asignado. Por
ejemplo, la expresión a = b asigna a la variable a el valor de la variable b y
devuelve dicho valor, mientras que la expresión c = a = b asigna a c y a el
valor de b (el operador = es asociativo por la derecha)
También se han incluido operadores de asignación compuestos que permiten
ahorrar tecleo a la hora de realizar asignaciones tan comunes como:
temperatura = temperatura + 15; // Sin usar asignación compuesta
temperatura += 15; // Usando asignación compuesta
Las dos líneas anteriores son equivalentes, pues el operador compuesto += lo
que hace es asignar a su primer operando el valor que tenía más el valor de su
segundo operando. Como se ve, permite compactar bastante el código.
Aparte del operador de asignación compuesto +=, también se ofrecen
operadores de asignación compuestos para la mayoría de los operadores
M.S. Diana Cecilia Muñoz Casanova - 70 -
Universidad Nacional del Santa Facultad de Ingeniería Manual de Teoría de lenguajes E. A. P Ingeniería de Sistemas e Informática Unidad II
binarios ya vistos. Estos son: +=, -=, *=, /=, %=, &=, |=, ^=, <<= y >>=.
Nótese que no hay versiones compuestas para los operadores binarios && y ||.
Otros dos operadores de asignación incluidos son los de incremento(++) y
decremento (--) Estos operadores permiten, respectivamente, aumentar y
disminuir en una unidad el valor de la variable sobre el que se aplican. Así,
estas líneas de código son equivalentes:
temperatura = temperatura + 1; // Sin usar asignación compuesta ni
incremento
temperatura += 1; // Usando asignación compuesta
temperatura++; // Usando incremento
Si el operador ++ se coloca tras el nombre de la variable (como en el ejemplo)
devuelve el valor de la variable antes de incrementarla, mientras que si se
coloca antes, devuelve el valor de ésta tras incrementarla; y lo mismo ocurre
con el operador --. Por ejemplo:
c = b++; // Se asigna a c el valor de b y luego se incrementa b
c = ++b; // Se incrementa el valor de b y luego se asigna a c
La ventaja de usar los operadores ++ y -- es que en muchas máquinas son más
eficientes que el resto de formas de realizar sumas o restas de una unidad, pues
el compilador traducirlos en una única instrucción en código máquina.
ASIGNACIÓN EN JSCRIPT.
En JScript, el operador de asignación se utiliza para asignar un valor a una
variable. El operador de igualdad compara dos valores.
Al igual que muchos lenguajes de programación, JScript utiliza el signo igual
(=) para asignar valores a variables: es el operador de asignación. El operando
situado a la izquierda del operador = debe ser un valor Lvalue, es decir, una
variable, un elemento de la matriz o una propiedad de objeto.
El operando situado a la derecha del operador = debe ser un valor Rvalue.
Puede utilizarse cualquier tipo de valor arbitrario como valor Rvalue, incluido
el valor resultante de una expresión.
M.S. Diana Cecilia Muñoz Casanova - 71 -
Universidad Nacional del Santa Facultad de Ingeniería Manual de Teoría de lenguajes E. A. P Ingeniería de Sistemas e Informática Unidad II
Ejemplo:
anInteger = 3;
JScript interpreta esta instrucción de la forma siguiente:
"Asignar el valor 3 a la variable anInteger"
o bien
"anInteger recibe el valor 3".
ASIGNACIÓN EN PHP
Ejemplo:
000 001 002
<? $miVariable = 'suValor';
?>
Combinando los operadores de aritmética, bit a bit o de cadenas con el
operador de asignación, conseguimos los 'operadores combinados', con los que
podemos realizar una operación de asignación conjuntamente con otra
operación:
000 001 002 003 004
<? $a = 1; $a += 1; // Sumamos y asignamos $a = $a + 1; // Operacion equivalente ?>
La forma en la que PHP maneja las referencias es uno de los principales
problemas con el que nos podemos encontrar al programar en este lenguaje.
Por defecto todas las asignaciones y pasos de parámetro se hacen por valor, de
forma que si hacemos una asignación de un objeto en otro, $obj_a = $obj_b, lo
que estamos haciendo es crear dos instancias distintas.
En una asignación $a =& $b, no estamos asignando a $a la dirección de
memoria de $b, estamos haciendo que la variable $a sea un alias de la variable
$b. Conviene tener esto en cuenta ya que este comportamiento puede hacer
que las cosas no funcionen como esperamos en algunas circunstancias.
Veamos un ejemplo para clarificar la situación.
M.S. Diana Cecilia Muñoz Casanova - 72 -
Universidad Nacional del Santa Facultad de Ingeniería Manual de Teoría de lenguajes E. A. P Ingeniería de Sistemas e Informática Unidad II
En PHP3, las variables siempre se asignan por valor. Esto significa que cuando
se asigna una expresión a una variable, el valor íntegro de la expresión original
se copia en la variable de destino. Esto quiere decir que, por ejemplo, después
de asignar el valor de una variable a otra, los cambios que se efectúen a una de
esas variables no afectará a la otra.
PHP4 ofrece otra forma de asignar valores a las variables: asignar por
referencia. Esto significa que la nueva variable simplemente referencia (en
otras palabras, "se convierte en un alias de" o "apunta a") la variable original.
Los cambios a la nueva variable afectan a la original, y viceversa. Esto
también significa que no se produce una copia de valores; por tanto, la
asignación ocurre más rápidamente.
Para asignar por referencia, simplemente se antepone un ampersand (&) al
comienzo de la variable cuyo valor se está asignando (la variable fuente).
Veamos un ejemplo:
M.S. Diana Cecilia Muñoz Casanova - 73 -
Universidad Nacional del Santa Facultad de Ingeniería Manual de Teoría de lenguajes E. A. P Ingeniería de Sistemas e Informática Unidad II
CAPÍTULO II: ACTIVACIÓN DE PROCEDIMIENTOS
2.1 CONCEPTO
Un procedimiento es un subprograma, es un grupo de instrucciones, variables,
constantes, etc, que están diseñados con un propósito particular y tiene su nombre
propio a las que se asigna un nombre (identificador) y constituye una unidad de
programa.
Un procedimiento es un modulo de un programa que realiza tareas especificas y
que no puede regresar valores al programa principal u a otro procedimiento que
lo este invocando.
Para invocarlo, es decir, para hacer que se ejecute, basta con escribir su nombre en
el cuerpo de otro procedimiento o en el programa principal. Pero, hay que tener
muy en cuenta que su declaración debe hacerse antes de que sea llamado por otro
módulo.
Un programa puede tener tantos procedimientos como se deseen, para hacer una
llamada o invocación al procedimiento durante la ejecución de un programa solo
se deberá escribir el nombre del procedimiento y los paréntesis en blanco.
Su interés de los procedimientos no radica en el resultado obtenido sino más bien
en las operaciones realizadas al ejecutarla (creación de un archivo, reenvío a otra
página,...). En lenguajes como el PHP las funciones y los procedimientos son
considerados como la misma cosa y para definirlos se hace usando los mismos
comandos. Tanto las variables como las funciones y los procedimientos deben ser
nombradas sin servirse de acentos, espacios ni caracteres especiales para no correr
riesgos de error.
Al introducir parámetros así como procedimientos de procedimientos
(subprocedimientos) los programas ahora pueden ser escritos en forma más
estructurada y libres de errores. Por ejemplo, si un procedimiento ya es correcto,
cada vez que es usado produce resultados correctos. Por consecuencia, en caso de
errores, se puede reducir la búsqueda a aquellos lugares que todavía no han sido
revisados.
De este modo, un programa puede ser visto como una secuencia de llamadas a
procedimientos. El programa principal es responsable de pasar los datos a las
M.S. Diana Cecilia Muñoz Casanova - 74 -
Universidad Nacional del Santa Facultad de Ingeniería Manual de Teoría de lenguajes E. A. P Ingeniería de Sistemas e Informática Unidad II
llamadas individuales, los datos son procesados por los procedimientos y, una vez
que el programa ha terminado, los datos resultantes son presentados. Así, el flujo
de datos puede ser ilustrado como una gráfica jerárquica, un árbol, como se
muestra en la Gráfica 2.
Gráfico Nº 2: Maquina de acceso Aleatorio
En el lenguaje Pascal tiene prácticamente la misma estructura que un programa.
Veamos las secciones que comparten y no comparten un procedimiento y un
programa principal:
Mientras que en el programa la cabecera consta de la
palabra reservada program seguida del nombre del programa, en un
procedimiento se compone de la palabra procedure seguida del nombre del
procedimiento y una lista de parámetros que es opcional.
Las secciones de declaración de constantes (const), de
tipos (type) y de variables (var) también pueden aparecer en la estructura de
cualquier procedimiento.
Respecto al cuerpo del procedimiento, decir que al igual
que el de un programa se delimita por las palabras reservadas begin y end, y en
su interior puede contener sentencias simples o estructuradas.
Por último, comentar que ambos difieren en el signo de
puntuación que marca su final, ya que en un programa es el punto y en un
procedimiento es el punto y coma.
M.S. Diana Cecilia Muñoz Casanova - 75 -
PROGRAMA PRINCIPAL(data)
PROGRAMA PRINCIPAL(data)
Procedimiento1Procedimiento1 Procedimiento2Procedimiento2 Procedimiento3Procedimiento3
PROGRAMA
Universidad Nacional del Santa Facultad de Ingeniería Manual de Teoría de lenguajes E. A. P Ingeniería de Sistemas e Informática Unidad II
2.2 DECLARACIÓN DE PROCEDIMIENTO
Una declaración de procedimiento tiene 3 partes:
El nombre del procedimiento declarado.
Los parámetros formales del procedimiento (pueden ser
opcionales).
Un cuerpo consistente en declaraciones locales y una lista de
enunciados.
Por ejemplo en Pascal, el procedimiento Sucesor, declarado mediante:
Gráfico Nº 3: Declaración de procedimiento en pascal
Cada ejecución del cuerpo en un procedimiento se conoce como activación del
procedimiento.
La regla para las invocaciones de procedimientos es la notación
prefija.
< Nombre procedimiento> (< parámetros formales>)
El tiempo de vida de las variables locales es solo cuando cada activación de un
procedimiento tiene sus propias variables locales y una vez que termina no
habrá necesidad de esas variables.
Por lo tanto el almacenamiento para variables locales se asigna cuando
comienza una activación y se libera cuando la activación termina.
M.S. Diana Cecilia Muñoz Casanova - 76 -
Cuerpo
Procedure Sucesor ( i: Integer );
Begin
calc := ( i + 1 ) % tamanno;
End;
Nombre Parámetro formal
Universidad Nacional del Santa Facultad de Ingeniería Manual de Teoría de lenguajes E. A. P Ingeniería de Sistemas e Informática Unidad II
2.3 VENTAJAS Y DESVENTAJAS DE LOS PROCEDIMIENTOS
Ventajas
Los errores son mas rápidos de encontrar
Son menos frecuentes los errores
Búsqueda mas exacta de errores
Independencia de la arquitectura física de la computadora
(portabilidad), esto significa que un mismo lenguaje puede funcionar (al
menos en teoría) en distintos computadores, por lo que tanto el lenguaje como
los programas escritos con él serán transportables de un computador a otro. En
la práctica, esta característica resulta limitada por la gran diversidad de
versiones y dialectos que se constituyen para cada lenguaje.
una sentencia en un lenguaje de alto nivel da lugar, al ser
traducida, a varias instrucciones en lenguaje máquina. Se llaman de
procedimientos porque están diseñados para expresar la lógica capaz de
resolver problemas generales.
Desventajas
Las características comunes entre dos entes no quedan explícitas.
El mundo en que vivimos se halla plagado de objetos: aviones,
trenes, automóviles, teléfonos, libros, computadoras, etc. Sin embargo, en esa
época las técnicas de programación no reflejaban esto. Lo procedural
[procedimientos] fue el paradigma principal de la programación, el cual define
un programa como un algoritmo escrito en algún lenguaje de programación.
Las razones de este énfasis son principalmente históricas, por lo tanto: con el
paradigma procedimental es más difícil modelar el mundo real.
La programación por procedimientos es adecuada para ciertas
cosas, pero a medida que los programas se van haciendo más complicados, y
las interacciones entre procedimientos más complejas, la programación
mediante procedimientos se hace muy dura de mantener, difícil de depurar
errores y por lo tanto muy compleja de actualizar.
M.S. Diana Cecilia Muñoz Casanova - 77 -
Universidad Nacional del Santa Facultad de Ingeniería Manual de Teoría de lenguajes E. A. P Ingeniería de Sistemas e Informática Unidad II
Otra de las desventajas de la programación basada en
procedimientos fue la aparición de pantallas gráficas y el interés subsecuente
en las aplicaciones utilizando ventanas. El acceso a una interfaz gráfica de
usuarios (GUI) donde un usuario puede moverse con facilidad alrededor de
una sola ventana es un desafío cuando se intenta lograrlo con un código
procedural. La programación múltiple y las posibles ventanas que se traslapan
en una misma pantalla gráfica simplemente aumenta la enorme complejidad
cuando se utiliza código procedural.
2.4 UTILIZACIÓN DE DATOS EN LOS PROCEDIMIENTOS
Hay dos modos de utilizar datos en los procedimientos y funciones:
Mediante variables globales del programa que cualquier
procedimiento puede reconocer
A través de los parámetros definidos para cada procedimiento o
función en particular
Ejemplo:
uses crt;
var num:integer; {variable global del programa}
procedure trazalinea(numero: integer); {traza una línea de 10 asteriscos}
var j:integer;
begin
for j:=1 to numero do
write(*);
writeln;
end; {trazalinea}
begin {programa principal}
num:= 8;
trazalinea(num); {num es el parámetro para el proc.}
end. {principal}
M.S. Diana Cecilia Muñoz Casanova - 78 -
Universidad Nacional del Santa Facultad de Ingeniería Manual de Teoría de lenguajes E. A. P Ingeniería de Sistemas e Informática Unidad II
2.5 MÉTODOS DE PASOS DE PARÁMETROS
2.5.1. INVOCACIÓN POR VALOR
Cuando un parámetro actual se pasa por valor, el subprograma hace una copia
del valor de éste en una posición de memoria idéntica en tamaño pero distinta
en ubicación a la del parámetro actual y la asigna al parámetro formal
correspondiente. Como el subprograma trabaja a partir de sus parámetros
formales, si durante la ejecución se modifica el valor de un parámetro formal
correspondiente a un paso por valor, el contenido de la posición de memoria
del parámetro actual no se verá alterado. Puede decirse que el paso por valor
es un canal de transferencia de información con una sola dirección, es decir,
de entrada al subprograma.
Gráfico Nº 4: Paso por valor
2.5.2. INVOCACIÓN POR REFERENCIA
O por variable: en el paso por referencia el parámetro formal queda asociado
a la misma posición de memoria que su correspondiente parámetro actual, por
lo que cualquier modificación que el subprograma realice sobre el contenido
del parámetro formal se efectúa sobre el parámetro actual correspondiente y
repercutirá en el programa principal o llamador. De todo esto se deduce que si
no queremos que un subprograma altere el contenido de un parámetro actual,
es decir, de una variable del programa principal, debemos realizar paso por
valor. Por el contrario, si queremos que un subprograma altere el valor de un
parámetro actual tenemos que pasarlo por variable o referencia. Si un
M.S. Diana Cecilia Muñoz Casanova - 79 -
Universidad Nacional del Santa Facultad de Ingeniería Manual de Teoría de lenguajes E. A. P Ingeniería de Sistemas e Informática Unidad II
parámetro actual es pasado por variable, este parámetro no puede ser ni una
constante, ni una expresión, sino que debe ser una variable, ya que no pueden
modificarse los contenidos de una constante ni de una expresión
Gráfico Nº 5: Paso por referencia
2.6 TIEMPO DE VIDA ANIMADA DE LAS ACTIVACIONES
El flujo normal de control entre las actividades de procedimientos en los lenguajes
imperativos puede resumirse con un árbol. Si p invoca a Q entonces P es el padre
de Q dentro del Árbol.
El tiempo de vida de una activación comienza cuando el control entra a la
activación y termina cuando el control lo abandona.
2.7 ESTRUCTURA DEL BLOQUE
Un bloque consiste en una secuencia de declaraciones incluyendo declaraciones de
procedimientos, y una secuencia de enunciados. Se dice que un lenguaje esta
estructurado en bloques si permite anidar bloques. La sintaxis de los bloques esta
dado por:
< lista de procedimientos>
Begin
<lista de enunciados>
End
2.7.1. PROPÓSITO DE LAS ESTRUCTURAS DE BLOQUE
Las declaraciones dentro de una estructura de bloque son visibles solo dentro
del bloque. El ámbito de toda declaración en un bloque consiste en ese bloque
y cualquier bloque anidado dentro de el, excepto en los huecos debido a
declaraciones anidadas. Dicho de otra manera, una aparición de un nombre no
M.S. Diana Cecilia Muñoz Casanova - 80 -
Universidad Nacional del Santa Facultad de Ingeniería Manual de Teoría de lenguajes E. A. P Ingeniería de Sistemas e Informática Unidad II
local se encuentra en el ámbito de la declaración más cercana en la que el
nombre este anidado. La estructura de bloque tiene algunos problemas
Legibilidad, los programas estructurados en el bloque pueden ser
difíciles de leer porque los enunciados dentro del cuerpo de un
procedimiento aparecen después de todas las declaraciones del
procedimiento, debido a lo cual pueden aparecer varias paginas después
del encabezado.
Sobrecarga en tiempo de ejecución, esta asociada con el acceso a las
variables no locales en un cuerpo de procedimiento anidado.
2.7.2. PROCEDIMIENTO COMO PARÁMETROS
Un procedimiento que pasa como parámetro carga con su ámbito léxico.
Es decir, cuando un procedimiento X se pasa como parámetro, se va con una
liga de acceso A.
Después cuando se invoca a X, A se utiliza como liga de acceso para ese
bloque.
2.8 DISPOSICIÓN DE TIPO DE DATO ASIGNABLE
Además de que se utilizan para verificar la consistencia de un programa, los tipos
en los lenguajes imperativos determinan la posición de datos en la maquina que
están implementados. El almacenamiento para variables locales se encuentra en la
pila del tiempo de ejecución, dentro del registro de activación de un
procedimiento.
Los datos asignados dinámicamente en tiempo de ejecución se conservan en el
montículo.
Disposición de los arreglos.
Después de la declaración de variables.
Var A: array [0...4] of integer
Los elementos del arreglo A aparecen en localidades consecutivas.
A[0] A[1] A[2] A[3] A[4]
Posiciones de Memoria
M.S. Diana Cecilia Muñoz Casanova - 81 -
Universidad Nacional del Santa Facultad de Ingeniería Manual de Teoría de lenguajes E. A. P Ingeniería de Sistemas e Informática Unidad II
Ejemplo:
2.9 APUNTADORES Y ASIGNACIÓN DINÁMICA DE VALORES
2.9.1. PUNTEROS
El valor de cada variable está almacenado en una dirección de
memoria.
Operador dirección (&):
Permite determinar la posición de memoria donde se encuentra
una variable. Ej int a; ... &a
Un puntero “apunta” a una variable si su contenido es la dirección de
esa variable.
Tipo de datos puntero: Contiene direcciones de variables. Una
variable de tipo puntero contendrá la dirección de memoria de otra
variable.
Operador indirección: Permite acceder al contenido de la variable a la
que “apunta” la variable de tipo puntero.
Cada variable de un programa tiene una dirección en la memoria del
ordenador. Esta dirección indica la posición del primer byte que la
variable ocupa. En el caso de una estructura es la suma del tamaño de
cada uno de sus campos. Como en cualquier caso las variables son
almacenadas ordenadamente y de una forma predecible, es posible
acceder a estas y manipularlas mediante otras variables que contenga su
dirección. A este tipo de variables se les denomina punteros.
2.9.2. VARIABLES ESTÁTICAS
M.S. Diana Cecilia Muñoz Casanova - 82 -
Universidad Nacional del Santa Facultad de Ingeniería Manual de Teoría de lenguajes E. A. P Ingeniería de Sistemas e Informática Unidad II
Son variables permanentes en su propia función o archivo. Se diferencian de
la variable global porque son desconocidas fuera de sus funciones o archivo,
pero mantienen sus valores entre llamadas. Esta característica las hace útiles
cuando se escriben funciones generales y bibliotecas de funciones.
2.9.3. VARIABLES DINÁMICAS
Son idénticas en su forma a las variables estáticas. La diferencia entre ellas es
la misma manera en que se crean y la forma como se acceden a ellas. Las
variables dinámicas si bien son creadas y destruidas durante la ejecución de
un programa, deben existir en algún otro lugar (es una zona de la memoria del
ordenador reservada por el compilador para almacenar las variables
dinámicas, esta zona se denomina “El espacio Heap”).
2.9.4. ESTRUCTURA DE DATOS LIGADOS.
Las celdas y las ligas se usan también para implementar estructuras de datos
como listas y árboles que tienen los tipos definidos recursivamente.
En las siguientes declaraciones, el tipo liga es un apuntador a celda y celda es
un registro con un campo de información y una liga simple hacia la celda
siguiente:
Info
2.9.5. OPERACIONES CON PUNTEROS
Para un puntero existe tres posibilidades: estar definido, apuntar a una
variable dinámica o no apuntar a nada.
Hacer que un puntero no apunte a ningún sitio implica asignarlo un valor
especial predefinido llamado NIL.
El mecanismo de la asignación de puntero es el siguiente:
Var
PtrA, PtrB: PtrReg;
New (PtrA);
New (PtrB);
PtrB: = PtrA;
M.S. Diana Cecilia Muñoz Casanova - 83 -
Liga a la siguiente celda
Universidad Nacional del Santa Facultad de Ingeniería Manual de Teoría de lenguajes E. A. P Ingeniería de Sistemas e Informática Unidad II
M.S. Diana Cecilia Muñoz Casanova - 84 -
Universidad Nacional del Santa Facultad de Ingeniería Manual de Teoría de lenguajes E. A. P Ingeniería de Sistemas e Informática Unidad II
CAPÍTULO III: ENCAPSULAMIENTO Y HERENCIA DE
DATOS
3.1 PARADIGMA DE LA PROGRAMACIÓN ORIENTADA A OBJETOS.
Para aquel que no es un programador, Orientación a Objetos significa algo
bastante familiar: considerar al mundo como un conjunto de entidades u objetos
que están relacionados y se comunican entre ellos. Esta es la forma en que la gente
normal ve el mundo, así es que este pensamiento tiene intrínsecamente sentido.
La Orientación a Objetos se basa en estas ideas: un programa es un mundo que
representa un subconjunto del mundo real. La estructura del programa se
simplifica en gran medida si cada una de las entidades u objetos del problema que
se está modelando corresponde directamente con un objeto que se puede
manipular internamente en un programa.
Para el desarrollo de sistemas, la orientación a objetos es un nivel de abstracción
de computadora más allá de los procedimientos y los datos. El elemento
fundamental de la POO es, como su nombre lo indica, el objeto. Podemos definir
un objeto como un conjunto complejo de datos y programas que poseen estructura
y forman parte de una organización.
Esta definición especifica varias propiedades importantes de los objetos. En
primer lugar, un objeto no es un dato simple, sino que contiene en su interior
cierto número de componentes bien estructurados. En segundo lugar, cada objeto
no es un ente aislado, sino que forma parte de una organización jerárquica o de
otro tipo.
El hecho de que el tema central sean los objetos, aunque intuitivamente, marca una
desviación significativa de los anteriores paradigmas de la programación.
M.S. Diana Cecilia Muñoz Casanova - 85 -
Universidad Nacional del Santa Facultad de Ingeniería Manual de Teoría de lenguajes E. A. P Ingeniería de Sistemas e Informática Unidad II
3.2 COMPONENTES BÁSICOS DE LA POO.
3.2.1. OBJETOS
Entidad de la vida real que tiene atributos (datos) y métodos (operaciones) que
operan sobre esos atributos. A los datos que forman parte del objeto se les
conoce como datos miembros y a las funciones como funciones miembros.
Los datos quedan ocultos al programador y únicamente dispondrá de las
funciones para acceder a ellos. Es una abstracción que se usa para representar
una entidad real. Todo objeto tiene estado, exhibe un comportamiento bien
definido y posee identidad única. Para crear objetos es necesario contar con
otro objeto que pueda crear objetos. El objeto creador de objetos se llama clase
y los objetos creados se llaman instancias.
Encapsulamiento
Porción visible: interfaz (protocolo)
Contrato público de comportamiento
Descripción de operaciones: información de entrada y de salida
Porción oculta: implementación
Estructura de datos para almacenar la información
Código que se ejecuta para realizar las operaciones
Gráfico Nº 6: Encapsulamiento de un objeto
M.S. Diana Cecilia Muñoz Casanova - 86 -
Universidad Nacional del Santa Facultad de Ingeniería Manual de Teoría de lenguajes E. A. P Ingeniería de Sistemas e Informática Unidad II
Invariantes de datos
Los datos de un objeto son inaccesibles desde el exterior, así que
la asignación de valores iniciales para estos datos pertenece al código
del objeto.
Estos valores iniciales se necesitan para establecer invariantes de
datos cuando se crea el objeto.
3.2.2. CLASE
Modelo que se usa para describir objetos similares. Es un tipo de dato definido
por el usuario que determina las estructuras de datos que lo forman y las
funciones asociadas con él, es decir es una descripción de un conjunto de
objetos casi idénticos. Una clase consta de métodos y datos que resumen las
características comunes de los objetos, incluyendo una descripción de cómo
crear un nuevo objeto de la clase. En otras palabras, las clases contienen los
anteproyectos para crear objetos.
Características de una clase.
Una clase tiene una parte pública y una parte privada.
La parte privada tiene que ver con el estado del objeto.
La parte pública es la interfaz al objeto.
Ejemplo
class Point {
private :
int xVal, yVal;
public:
void SetPt(int,int);
void OffsetPt(int,int);
};
Se declara una clase llamada Point.
Tiene cuatro componente. xVal, yVal, SetPt y OffsetPt.
Tiene dos datos miembros y dos funciones miembros.
M.S. Diana Cecilia Muñoz Casanova - 87 -
Universidad Nacional del Santa Facultad de Ingeniería Manual de Teoría de lenguajes E. A. P Ingeniería de Sistemas e Informática Unidad II
La parte privada está compuesta por los datos miembros.
La parte pública esta compuesta por las funcionesmiembros y la
forma en como podrá accesarse los objetos.
No importa el orden de la parte pública y privada.
3.2.3. MENSAJE
Es una petición de un objeto a otro para que este se comporte de una
determinada manera, ejecutando uno de sus métodos.
El nombre del método y
Los argumentos del método.
Por consecuencia, la invocación de un método es solamente una reacción
causada por el hecho de recibir un mensaje. Esto solamente es posible si el
método es realmente conocido por el objeto.
Para proporcionarte una comprensión acerca de esta comunicación, Tenemos
la siguiente clase (Definida en Lenguaje C):
class Integer {
attributes:
int i
methods:
setValue(int n)
Integer addValue(Integer j)
}
Nosotros podíamos crear nuevos objetos e invocar métodos sobre ellos. Por
ejemplo, podíamos usar:
Integer i; /* Definir un nuevo objeto integer */
i.setValue(1); /* Ponerle el valor 1 */
Para expresar el hecho de que el objeto integer i debería poner su valor a 1.
Este es el mensaje "Aplica el método setValue con argumento 1 sobre tí
mismo." enviado al objeto i. Nosotros usamos la notación "." para el envío de
M.S. Diana Cecilia Muñoz Casanova - 88 -
Universidad Nacional del Santa Facultad de Ingeniería Manual de Teoría de lenguajes E. A. P Ingeniería de Sistemas e Informática Unidad II
un mensaje. Esta notación se usa también en C++ ; otros lenguajes orientados
a objetos pueden usar otras notaciones, por ejemplo “->”.
Mandar un mensaje pidiéndole a un objeto que aplique un método es similar a
una llamada a un procedimiento en lenguajes de programación "tradicionales".
Sin embargo, en orientación a objetos, hay un cuadro de objetos autónomos
que se comunican unos con los otros por medio de el intercambio de mensajes.
Los objetos reaccionan cuando reciben mensajes por medio de la aplicación de
métodos sobre si mismos. También pueden negar la ejecución de un método,
por ejemplo si el objeto que hace la llamada no tiene permiso para ejecutar el
método solicitado.
En nuestro ejemplo, el mensaje y el método que debía ser aplicado una vez que
el mensaje se hubiera recibido, tienen el mismo nombre : Nosotros mandamos
"setValue con argumento 1" al objeto i el cuál aplica "setValue(1)".
Gráfico Nº 7: Mensajes entre objetos.
3.3 MANEJO AUTOMÁTICO DE MEMORIA.
En un programa con orientación a objetos ocurren tres sucesos:
1) Se crean los objetos cuando se necesitan.
2) Los mensajes se mueven de un objeto a otro a medida que el programa
procesa internamente información o responde a la entrada de los usuarios.
3) Se borran los objetos cuando ya no son necesarios y se recupera memoria.
M.S. Diana Cecilia Muñoz Casanova - 89 -
Universidad Nacional del Santa Facultad de Ingeniería Manual de Teoría de lenguajes E. A. P Ingeniería de Sistemas e Informática Unidad II
El primer suceso dice: "Se crean los objetos cuando se necesitan." y el tercer
suceso indica: "Se borran los objetos cuando ya no son necesarios y se recupera la
memoria.". Estos sucesos se desarrollan con los constructores y destructores.
Constructores.
Los constructores son procedimientos de la clase que permiten crear objetos.
Un constructor es llamado para asignar memoria a un objeto, para asignar
valores a los datos del objeto y realizar tareas iniciales para un nuevo objeto.
Esto implique que si no podemos trabajar con un objeto que no haya sido
creado a través de un constructor y si sólo se pueden modificar mediante los
procedimientos de la clase, no tenemos forma de corromper el objeto, lo
cual aumenta la confiabilidad y facilita la rehusabilidad.
Destructores
Un destructor es un procedimiento de la clase que realiza la tarea opuesta a su
constructor, libera la memoria que fue asignada al objeto que fue creado por el
constructor. Es deseable que el destructor se invoque implícitamente cuando
el objeto abandone el bloque donde fue declarado.
El destructor le permite al programador despreocuparse de tener que liberar la
memoria que deja de utilizar y correr el riesgo de que ésta se sature.
Normalmente en los lenguajes con orientación a objetos el destructor como el
constructor tienen el mismo nombre de la clase a la que pertenece.
Ejemplo:
Constructor iniciar (real 1, real 2)
x = real 1
y = real 2
Destructor iniciar
borra x
borra y
M.S. Diana Cecilia Muñoz Casanova - 90 -
Universidad Nacional del Santa Facultad de Ingeniería Manual de Teoría de lenguajes E. A. P Ingeniería de Sistemas e Informática Unidad II
3.4 CARACTERÍSTICAS FUNDAMENTALES DE LA POO
1. Encapsulamiento: Es la ocultación de información. Significa mantener
la información dentro del objeto y mantenerlo como una caja negra. Puede ser
accedida por métodos.
2. Abstracción: Es la capacidad de aislar y encapsular la información del
diseño y la ejecución. Es la capacidad para identificar atributos y métodos.
3. Herencia: Es la propiedad que permite a los objetos crearse a partir de
otros objetos. Cada subclase comparte características comunes con la clase de
la que deriva. La clase original la llamamos clase base y las nuevas clases
creadas a partir de ella clases derivadas. Una clase derivada puede ser
también clase base dando lugar a una jerarquía de clases.
Los miembros de la clase base deben ser protected o private protected.
La clase derivada hereda todos los datos y funciones miembro, pero solo
puede acceder a los miembros que le sean permitidos desde la clase base.
La ventaja de la herencia es que permite la reutilización de código, ahorrando
tiempo y dinero.
4. Polimorfismo: Es la capacidad de que diferentes objetos reaccionen de
distinta forma a un mismo mensaje. Es la capacidad de referirse a objetos de
clases distintas en una jerarquía utilizando el mismo elemento de programa
(método) para realizar la misma operación, pero de manera diferente.
Ejemplo:
Operación Resultado
3+7
0.1+11.001
“ho” + “la”
12
11.101
“hola”
Si la asignación del tipo del objeto referenciado ocurre durante la ejecución
del programa, se habla de asignación tardía/dinámica. Otra opcion es
resolverlo ya en tiempo de compilación.
M.S. Diana Cecilia Muñoz Casanova - 91 -
Universidad Nacional del Santa Facultad de Ingeniería Manual de Teoría de lenguajes E. A. P Ingeniería de Sistemas e Informática Unidad II
3.5 ENCAPSULAMIENTO DE DATOS
El empaque conjunto de datos y métodos se llama encapsulado. El objeto esconde
sus datos de los demás objetos y permite el acceso a los datos mediante sus
propios métodos. Esto recibe el nombre de ocultamiento de información. El
encapsulamiento evita la corrupción de los datos de un objeto. Si todos los
programas pudieran tener acceso a los datos de cualquier forma que quisieran los
usuarios, los datos se podrían corromper o utilizar de mala manera. El encapsulado
protege los datos del uso arbitrario y no pretendido.
El encapsulado oculta los detalles de su implantación interna a los usuarios de un
objeto. Los usuarios se dan cuenta de las operaciones que puede solicitar del
objeto, pero desconocen los detalles de cómo se lleva a cabo la operación. Todos
los detalles específicos de los datos del objeto y la codificación de sus operaciones
están fuera del alcance del usuario.
El encapsulado, al separar el comportamiento del objeto de su implantación,
permite la modificación de ésta sin que se tengan que modificar las aplicaciones
que lo utilizan. No es necesario conocer los detalles de la implementación y/o
diseño para poder utilizar algún código. Al ocultar información “no necesaria” se
protege las otras partes del programa de cambios en el dado caso que cambia la
parte escondida.
En la sección 3.2.1 (Objetos) muestra la manera de cómo esta encapsulado los
datos de un objeto.
3.6 HERENCIA DE DATOS
Un tipo de objeto puede tener subtipos. Por ejemplo, el tipo de objeto persona
puede tener subtipos estudiante y empleado. A su vez, el tipo de objeto estudiante
puede tener como subtipo estudiante de pregrado y estudiante de postgrado,
mientras que empleado puede tener como subtipo a académico y administrativo.
Existe de este modo una jerarquía de tipos, subtipos, subsubtipos, etc.
Una clase implanta el tipo de objeto. Una subclase hereda propiedades de su clase
padre; una sub-subclase hereda propiedades de las subclases; etc. Una subclase
M.S. Diana Cecilia Muñoz Casanova - 92 -
Universidad Nacional del Santa Facultad de Ingeniería Manual de Teoría de lenguajes E. A. P Ingeniería de Sistemas e Informática Unidad II
puede heredar la estructura de datos y los métodos, o algunos de los métodos, de
su superclase. También tiene sus métodos e incluso tipos de datos propios.
Ejemplo:
Superclase Subclase
class Point {
attributes:
int x, y
methods:
setX(int newX)
getX()
setY(int newY)
getY()
}
class Circle inherits from Point {
atrributes:
int radius
methods:
setRadius(int newRadius)
getRadius()
}
La clase Circle hereda todos los elementos de datos y métodos de la clase Point.
No hay necesidad de definirlos dos veces: Solamente usamos los ya existentes (y
familiares) datos y definiciones de métodos.
Al nivel de objeto ahora podemos usar un círculo justamente como habríamos
usado un punto, debido a que un círculo es-un(a) punto. Por ejemplo, podemos
definir un objeto círculo y establecer sus coordenadas del punto central :
Circle acircle
acircle.setX(1) /* Heredado de Point */
acircle.setY(2)
acircle.setRadius(3) /* Añadido por Circle */
M.S. Diana Cecilia Muñoz Casanova - 93 -
Superclase
Subclase
Universidad Nacional del Santa Facultad de Ingeniería Manual de Teoría de lenguajes E. A. P Ingeniería de Sistemas e Informática Unidad II
3.6.1. TIPOS DE HERENCIA
Herencia simple.
Un objeto puede extender las características de otro objeto y de ningún
otro, es decir, solo puede tener un padre, aquí se encuentran los lenguajes
Java, Ada y C#.
Herencia múltiple:
Un objeto puede extender las características de uno o más objetos, es decir,
puede tener varios padres. Esto permite que la subclase herede propiedades
de más de una superclase y "mezclar" sus propiedades.
En este aspecto hay discrepancias entre los diseñadores de lenguajes.
Algunos de ellos han preferido no admitir la herencia múltiple por las
posibles coincidencias en nombres de métodos o datos miembros.
Gráfico Nº 8: Herencia múltiple.
Si la clase A hereda de más de una clase, por ej. A hereda de B1, B2, ...,
Bn, hablamos de herencia múltiple. Esto puede presentar conflictos de
nomenclatura en A si al menos dos de sus superclases definen
propiedades con el mismo nombre.
La definición de arriba presenta conflictos de nomenclatura los cuáles
ocurren si más de una superclase de una subclase usan el mismo nombre
para ambos, atributos o métodos. Por ejemplo, supongamos que la clase
M.S. Diana Cecilia Muñoz Casanova - 94 -
Universidad Nacional del Santa Facultad de Ingeniería Manual de Teoría de lenguajes E. A. P Ingeniería de Sistemas e Informática Unidad II
String define un método setX() que pone el string en una secuencia de "X"
caracteres. Se produce la pregunta ¿Que debería ser heredado por
DrawableString(clase hija)? ¿La versión de Point(clase definida en el
ejemplo de la seccion 3.6 HERENCIA DE DATOS), de String o ninguna
de las dos?
Estos conflictos pueden ser resueltos de al menos dos maneras:
El orden en el cuál las superclases son provistas, definen que
propiedad será accesible por el nombre causante del conflicto. Los
otros quedarán "escondidos".
Las subclases deben resolver el conflicto proveyendo una
propiedad con el nombre y definiendo como usar los de sus
superclases.
La primera solución no es muy conveniente ya que presentan
consecuencias implícitas dependiendo del orden en el cuál las clases
heredan unas de otras. Para el segundo caso, las subclases deben redefinir
explícitamente las propiedades que están involucradas en conflictos de
nomenclatura. Un tipo especial de conflicto de nomenclatura se presenta si
una clase D hereda en forma múltiple de las superclases B y C que a su vez
son derivadas de una superclase A. Esto conduce a una gráfica de herencia
como se muestra a continuación:
Gráfico Nº 9: Un conflicto de nomenclatura presentado por una
superclase compartida por superclases usadas en herencia múltiple
M.S. Diana Cecilia Muñoz Casanova - 95 -
Universidad Nacional del Santa Facultad de Ingeniería Manual de Teoría de lenguajes E. A. P Ingeniería de Sistemas e Informática Unidad II
Cabe la pregunta acerca de que propiedades hereda realmente la clase D de
sus superclases B y C. Algunos lenguajes de programación existentes
resuelven esta gráfica de herencia especial derivando D con:
las propiedades de A más
las propiedades de B y C sin las propiedades que han heredado de
A.
Consecuentemente, D no puede presentar conflictos de nomenclatura con
los nombres en la clase A. Sin embargo, si B y C añaden propiedades con
el mismo nombre, D entra en un conflicto de nomenclatura.
Otra posible solución es que D herede de ambas trayectorias de herencia.
En esta solución, D tiene dos copias de las propiedades de A: una heredada
de B y otra de C.
Aunque la herencia múltiple es un poderoso mecanismo en orientación a
objetos, los problemas que se presentan con los conflictos de nomenclatura
ha llevado a varios autores a "condenarla". Debido a que los resultados de
la herencia múltiple siempre puede ser lograda usando herencia simple,
algunos lenguajes orientados a objetos no permiten siquiera su uso. Sin
embargo, usada con cuidado, bajo algunas condiciones la herencia múltiple
provee una manera eficiente y elegante de formular cosas.
3.7 CONSTRUCTORES PARA LA CONSTRUCCIÓN DE PROGRAMAS
A pesar de que los módulos y clases pueden coleccionar variables y
procedimientos, se consideran ciertas diferencias entre ambos:
Los módulos dividen el texto estático de un programa,
Mientras que las clases pueden usarse, además para describir objetos
dinámicos que existen en tiempo de ejecución.
3.7.1. PROCEDIMIENTOS.
M.S. Diana Cecilia Muñoz Casanova - 96 -
Universidad Nacional del Santa Facultad de Ingeniería Manual de Teoría de lenguajes E. A. P Ingeniería de Sistemas e Informática Unidad II
Los procedimientos han estado en uso desde los primeros días de la
computación. Entre los beneficios de los procedimientos se hallan los
siguientes:
Abstracción de operaciones.
El usuario solo necesita saber lo que el procedimiento hace y no como
esta implementado. Los procedimientos pueden usarse para dividir un
programa de manera que las operaciones en el pueden entenderse
aisladamente.
Extensiones del lenguaje.
Los conjuntos normalizados de procedimientos útiles son una forma de
extender el lenguaje.
3.7.2. MÓDULOS.
Un módulo divide el texto de un programa en piezas manejables.
Los módulos son estáticos, no podemos crear dinámicamente
módulos nuevos o copias de las existentes mientras se ejecuta un
programa.
Un módulo sirve como una caja negra con la cual el resto del
programa interactúa a través de una interfaz.
La interfaz de un módulo es una declaración de tipos,
variables, procedimientos, etc.
La implantación de un módulo abarca el código de los
procedimientos y los demás aspectos que constituyen el módulo.
Las interfaces y las implantaciones también se conocen como vistas
publicas y privadas de un módulo respectivamente
Ejemplo:
Modulo tabla Procedure inserta;Procedure encuentra;Const limiteVar Tab, dispo;
M.S. Diana Cecilia Muñoz Casanova - 97 -
Universidad Nacional del Santa Facultad de Ingeniería Manual de Teoría de lenguajes E. A. P Ingeniería de Sistemas e Informática Unidad II
.......Cuerpo del procedimiento.......
3.7.3. CLASES.
Podemos crear y destruir objetos mientras se ejecuta el programa. Cada clase
tiene un procedimiento constructor el cual se invoca para dar valores iniciales
a un objeto de la clase recién creada, y un procedimiento destructor el cual se
invoca justo antes de que el objeto desaparezca.
3.8 CLASES DERIVADAS Y OCULTACIÓN DE LA INFORMACIÓN
La clase D puede definirse como la extensión de la clase B mencionando solo
los cambios que se harán en B.
Es decir el punto de partida B se conoce como clase básica y la extensión D
como clase derivada.
3.8.1. Visibilidad de la información (Ocultamiento).
En general, se tienen tres palabras clave:
Public,
Private,
Protected
Para controlar la visibilidad de los nombres de los miembros de una
declaración de clase.
Los miembros públicos son visibles para el código exterior, no así los
miembros privados.
Los miembros protegidos son visibles a través de la herencia para las
clases derivadas pero no lo son para otros códigos.
M.S. Diana Cecilia Muñoz Casanova - 98 -
Universidad Nacional del Santa Facultad de Ingeniería Manual de Teoría de lenguajes E. A. P Ingeniería de Sistemas e Informática Unidad II
CAPÍTULO IV: PROGRAMACIÓN FUNCIONAL
4.1 CONCEPTO
La programación funcional es un paradigma de programación declarativa basado
en la utilización de funciones matemáticas.
Los programas escritos en un lenguaje funcional están constituidos únicamente por
definiciones de funciones, entendiendo éstas no como subprogramas clásicos de un
lenguaje imperativo (pues la programación funcional es declarativa), sino como
funciones puramente matemáticas, en las que se verifican ciertas propiedades
como la transparencia referencial (el significado de una expresión depende
únicamente del significado de sus subexpresiones), y por tanto, la carencia total de
efectos laterales.
4.2 EL OBJETIVO
Es conseguir lenguajes expresivos y matemáticamente elegantes, en los que no sea
necesario bajar al nivel de la máquina para describir el proceso llevado a cabo por
el programa.
4.3 CARACTERÍSTICAS PROPIAS DE ESTOS LENGUAJES
Son la no existencia de asignaciones de variables y la falta de construcciones
estructuradas como la secuencia o la iteración (lo que obliga en la práctica a
que todas las repeticiones de instrucciones se lleven a cabo por medio de
funciones recursivas).
La Programación Funcional es caracterizada por el uso de Expresiones y
Funciones.
Existen además otras características que sirven para identificarla y aumentar su
potencial en el desarrollo de aplicaciones:
M.S. Diana Cecilia Muñoz Casanova - 99 -
Universidad Nacional del Santa Facultad de Ingeniería Manual de Teoría de lenguajes E. A. P Ingeniería de Sistemas e Informática Unidad II
a) Funciones de orden superior: Cuando una función puede servir como
argumento de otra o puede almacenarse como valor en una estructura de
datos, o bien cuando el resultado de una función es otra función. Esto
proporciona una herramienta que maximiza el uso de la recursividad y el
anidamiento, y permite un desarrollo más eficiente de aplicaciones.
b) Sistemas de interferencias de tipos: Mecanismo que exime al
programador de la responsabilidad de declarar los tipos de las funciones
declaradas, y le permite al compilador deducir el tipo de datos al que están
asociadas las expresiones, basándose en la evidencia que presenta el
código al tiempo de la compilación del programa.
c) Polimorfismo paramétrico: Permite que una determinada función
tenga la capacidad de aceptar como parámetros una variedad de tipos
distintos cada vez que sea llamada, sin que esto influya en que la función
pueda obtener y regresar el resultado esperado.
d) Evaluación perezosa: Una función intentará evaluar los parámetros
con los que fue definida, para efectuar las reducciones que nos permitan
obtener el valor de la función.
4.4 CATEGORÍAS DE LENGUAJES FUNCIONALES
Los funcionales puros
Los híbridos.
La diferencia entre ambos estriba en que los lenguajes funcionales híbridos son
menos dogmáticos que los puros, al permitir conceptos tomados de los lenguajes
imperativos, como las secuencias de instrucciones o la asignación de variables. En
contraste, los lenguajes funcionales puros tienen una mayor potencia expresiva,
conservando a la vez su transparencia referencial, algo que no se cumple siempre
con un lenguaje híbrido.
M.S. Diana Cecilia Muñoz Casanova - 100 -