Introducción a Eiffel - Departamento de Lenguajes y Sistemas

Anuncio
Universidad de Granada
E.T.S. Ingeniería Informática
Eiffel
Diego Montesinos Hervás
Irene Díaz Valenzuela
Andrés Herrera del Pino
José Antonio Sáez Muñoz
3º Ingeniería Informática
Programación Dirigida a Objetos
Grupo B - Curso 2006-2007
1
1.Introducción
2
1.Introducción
Eiffel es un lenguaje de programación orientado a
objetos centrado en la construcción de software
robusto.
Diseñado por Bertrand Meyer, apareció en 1985 y
fué desarrollado por Meyer y Eiffel Software.
Eiffel es un lenguaje con tipos fuertes, pero relajado
por herencia. Implementa administración automática
de memoria, generalmente mediante algoritmos de
recolección de basura.
3
1.1 Características esenciales
- Mecanismos de ayuda al Diseño por contrato que
se integraron firmemente con el mecanismo de
herencia y otras construcciones del lenguaje.
- Estructura de programa orientada a objetos, las
clases son la unidad básica.
- Asignación estática de tipos.
- Ayuda para la gestión automática de memoria,
implementada por el recolector de basura.
- Papel central de la herencia, incluyendo herencia
múltiple y mecanismo para hacerla segura.
4
1.1 Características esenciales
- Un sistema uniforme de tipos que maneja las semanticas
de referencia y valor, donde todos los tipos (incluyendo los
tipos básicos) están basados en clases.
- Tipos genéricos.
- ‘Bloques‘(agent) (similares a los de Smalltalk)
- Rutinas 'once' (evaluadas solamente la primera vez), para la
compartición de objetos e inicialización.
- Sintaxis basada en las palabras clave de ALGOL/Pascal
pero sin separador (se puede usar el punto y coma, es
5
opcional).
1.2 Características de diseño
- Eiffel enfatiza en sentencias declarativas sobre
código procesal.
- Eiffel evita los trucos de codificación o técnicas de
codificación previstas.
- Se intenta no sólo hacer código más legible, sino
también permitir a los programadores concentrarse en
los aspectos importantes del programa sin meterse
en detalles de implementación.
6
1.2 Características de diseño
–La
simplicidad de Eiffel se ha pensado para promover
respuestas simples, extensibles y reutilizables para los
problemas de computación.
–Los
compiladores proveen técnicas de optimización con el
objetivo de crear código extremadamente eficiente,
comparable a C++, por ejemplo.
–Al
igual que los lenguajes de programación vistos en la
asignatura, Eiffel también utiliza semántica en el heap.
7
2.Características
de Eiffel
8
2.Características
La meta del lenguaje, bibliotecas, y
métodos de programación es crear un
software que utilice módulos lo más
reutilizables posible.
9
2.1 Eiffel soporta...
Herencia múltiple: permite que una
clase herede de varias superclases.
Además posibilita a los subtipos
adaptarse a sus propiedades
heredades renombrándolas o
estableciendo reglas de selección
para ellas.
●
10
2.1 Eiffel soporta...
Tipos genéricos: Eiffel usa tipos
parametrizados (genéricos), como en
otros lenguajes como Ada, Java, C#,
que permiten definir un tipo sin
especificar todos los otros tipos que
usa. Los tipos no especificados son
sustituidos por parámetros en estos
puntos del código.
●
11
2.1 Eiffel soporta...
Polimorfismo: capacidad que tienen
objetos de diferentes clases de responder
al mismo mensaje. Esto significa que
puede haber muchos mensajes con el
mismo nombre, en diferentes clases.
Cada clase responde al mensaje con su
código propio (método).
●
12
2.1 Eiffel soporta...
Encapsulación : ocultamiento del estado, es decir,
de los datos miembro, de un objeto de manera que
sólo se puede cambiar mediante las operaciones
definidas para ese objeto.
●De esta forma, el usuario de la clase puede obviar la
implementación de los métodos y propiedades para
concentrarse sólo en cómo usarlos. Por otro lado se
evita que el usuario pueda cambiar su estado de
maneras imprevistas e incontroladas.
●
13
2.1 Eiffel soporta...
Asignación fuerte de tipos
●En LPs con tipos, una expresión de valores está
bien formada cuando a su valor se le puede
asignar un tipo, ya sea en tiempo de compilación o
de ejecución.
●No se procede a la evaluación si no se ha podido
determinar por inferencia dicho tipo
●Podríamos hablar de tipo de la expresión
●Los LPs en que las expresiones han de ser
consistentes respecto a los tipos se dice que son
LPs con asignación fuerte de tipos
●
14
2.1 Eiffel soporta...
Equivalencia de métodos y tipos: como
ya sabemos de otras asignaturas, en
algunos LPs, si S es subtipo de T, podemos
utilizar S donde se espere un parámetro de
tipo T, y si una función devuelve un tipo T,
podría devolver tipo S sin problema ninguno.
●Por extensión, donde corresponde una
clase cualquiera, nos podemos encontrar
con cualquier subclase suya.
●
15
2.2 Contribución de Eiffel
Su contribución más importante a la ingeniería del
software es el Diseño por Contracto (DbC), en el
cual se tienen:
●
−
−
−
−
Assertions(afirmaciones)
Precondiciones
Postcondiciones
Invariantes de clase
que son usadas para asegurar la corrección
del programa sin sacrificar la eficiencia.
16
2.2 Contribución de Eiffel
• Assertions(afirmaciones)
En Eiffel, las afirmaciones son
integradas en el lenguaje y son
extraídas automáticamente para
generar la documentación de la
clase.
17
2.2 Contribución de Eiffel
Una afirmación es un predicado (por ejemplo, una
expresión booleana) situada en un programa para
indicar que la afirmación es verdad en ese lugar. Por
ejemplo, el siguiente código contiene dos
afirmaciones:
●x:= 5;
{x > 0}
x:= x + 1
{x > 1}
●Se usan para ayudar a la especificación de
programas y asegurar la corrección del código.
●
18
2.2 Contribución de Eiffel
Algunos lenguajes de programación modernos incluyen la
sentencia de afirmación (assert(cond)) que es una condición
que se comprueba en tiempo de ejecución. Si la evaluación
de la condición falla, se produce un fallo de afirmación como
resultado, el cual puede causar que la ejecución se aborte o
puede causar el reconsiderar una vía alternativa para el
programa.
●El uso de afirmaciones ayuda al programador a diseñar,
desarrollar y comprobar la corrección del código. Además
permite hacer comprobaciones durante el proceso de pruebas,
durante la ejecución, y detectar los posibles fallos, permitiendo
al programador detectar bugs de sus programas.
●
19
2.2 Contribución de Eiffel
Precondiciones:
●Es una afirmación (condición o predicado) que
debe ser siempre verdadero al principio de la
ejecución de alguna sección de código.
●Si la precondición falla, el efecto de la sección de
código puede estar indefinido y puede que se
produzcan errores en la ejecución.
●Ejemplo: para calcular el factorial de un número
la precondición es que el número sea mayor o
igual que 0.
●
20
2.2 Contribución de Eiffel
Postcondiciones:
●Es una afirmación (condición o predicado) que
debe ser siempre cierto justo después de la
ejecución de un algún trozo de código.
●Ejemplo: Para una función que calcule el
factorial, la poscondición puede ser que el
resultado sea siempre mayor o igual que 1.
●
21
2.2 Contribución de Eiffel
Invariante de representación.
●Es una serie de condiciones impuestas sobre los
objetos de una clase que determinan si un objeto
está o no bien formado.
●Los métodos de la clase deben preservar el
invariante de representación.
●Los invariantes de representación son establecidos
durante la construcción y continuamente se mantiene
tras las llamadas a los métodos públicos.
●
22
2.2 Contribución de Eiffel
El diseño de Eiffel está basado en la teoría de la
programación orientada a objetos.
●El lenguaje tiene un soporte formal para tipos
abstractos de datos.
●Bajo el correcto diseño de texto software se debe ser
capaz de reproducir una documentación para el
diseño final del software a partir de la información de
la implementación que está formalizada para el “tipo
abstracto de dato”.
●
23
2.3 Implementaciones y entornos
• EiffelStudio es un entorno de desarrollo integrado
(código libre o licencias comerciales). Es un
entorno orientado a objetos que usa técnicas de
interfaz de usurario como el pick-and-drop.
• EiffelEnvision es un pluggin para Microsoft Visual
Studio, que permite a los usuarios editar ,compilar y
depurar programas en Eiffel al usar Microsoft Visual
Studio IDE.
24
2.3 Implementaciones y entornos
●
Existen dos implementaciones de código libre:
−
−
●
●
SmartEiffel (implementacion GNU, basada en una
versión anterior del lenguaje)
Visual Eiffel.
Originalmente, el lenguaje Sather estaba basado en
Eiffel, pero fue modificándose, y ahora incluye
varias características de la programación funcional.
Parte de Apple Media Tool está basado en Eiffel.
25
2.4 Especificaciones y estándares
El lenguaje Eiffel es un estándar
internacional de la ISO (International
Organization for Standardization).
●
El estándar fue desarrollado por ECMA
International y su primera versión fue aprobada
por ECMA el 21 de Junio de 2005 como el
standard ECMA 367 (Eiffel: Analysis, Design
and Implementation Language)
●
26
2.4 Especificaciones y estándares
●
●
●
La segunda edición fue adoptada por ECMA en
Junio de 2006 y en el mismo año por la ISO
(Noviembre de 2006).
El desarrollo software de Eiffel y de sus bibliotecas,
dio lugar a implementar un estándar; Eiffel
Software's EiffelStudio 5.7, que implementa
algunos de los mejores mecanismos del lenguaje.
El equipo de SmartEiffel se apartó de este estándar
para crear su porpia versión del lenguaje, el cual
parece está más cerca del estilo original de Eiffel.
27
2.4 Especificaciones y estándares
Bibliografía de especificación del lenguaje Eiffel:
●
Bertrand Meyer: Eiffel: The Language, Prentice Hall,
segunda edición, 1992 (primera edición: 1991)
●
Bertrand Meyer: Standard Eiffel, 1997.
●
Bertrand Meyer: Object-Oriented Software Construction,
Prentice Hall: primera edición, 1988; segunda edición, 1997.
●
28
3.Cómo programar
en Eiffel
29
3.Cómo programar en Eiffel
Un programa en Eiffel es un conjunto de clases.
Pueden definirse conjuntos de clases denominados cluster.
Estos conjuntos pueden subdividirse en subclusters
anidados
Las clases contienen features que son similares a los
métodos en otros lenguajes.
En una clase se definen sus invariantes y contienen otras
propiedades tales como las notes que es una sección para
incluir la documentación.
Los tipos de datos estándar son también clases.
Todo sistema tiene una clase denominada root, que
contendrá un constructor llamado root procedure. Para
ejecutar un programa en Eiffel se debe crear una instancia
de la clase root y ejecutar su root procedure.
30
3.Cómo programar en Eiffel
Existen seis instrucciones básicas en Eiffel:
asignación, creación de objetos, llamada a
rutinas, condicional y selección.
Para facilitar la abstracción de datos y el
ocultamiento de información, Eiffel, igual que
ocurría en SmallTalk no permite la asignación entre
variables de instancia de los objetos, sino que
necesita de una interfaz para manejar los datos.
El concepto de “diseño por contrato” es central en
Eiffel, sus mecanismos están muy integrados en el
lenguaje. Las características del contrato se
extienden por medio de la herencia.
31
3.1 Ejemplo de programa en Eiffel
class
HELLO_WORLD
create
make
feature
make is
do
io.put_string (“Hello
World!”)
io.put_new_line
end
end
32
3.2 Descripción de una clase
Una clase contiene un conjunto de feature (métodos). Como las
clases representan un conjunto de objetos, un feature es una
operación sobre estos objetos. Estas pueden ser de dos tipos:
●
Consultores, que dan información sobre una instancia
Órdenes que modifican una instancia.
Esta distinción es importante en los métodos de Eiffel. En particular:
●
Principio de Acceso Uniforme: desde el exterior cualquier
consultor es un atributo o el resultado de una operación. La
notación es la misma en ambos casos.
Principio de separación entre las órdenes y consultores.
Esto no es una regla del lenguaje, pero se entiende como una
buena práctica de programación que no se realicen cambios en
el mismo.
33
3.3 Sobrecarga
Eiffel soporta la sobrecarga de funciones y operadores, es
decir, los nombres de funciones pueden volver a usarse en
diferentes clases, pero siempre haciendo referencia al mismo
comportamiento.
●Para hacer uso de esta funcionalidad simplemente tenemos
que asignar el mismo nombre a distintos feature en las distintas
clases implicadas. Veamos un ejemplo con el operador +
a + b for a,b: INTEGER
a + b for a,b: REAL
a + b for a,b: VECTOR [INTEGER]
●Sin embargo, Eiffel no soporta la sobrecarga de funciones
dentro de una misma clase como ocurre en otros lenguajes
como C++, por tanto, las funciones f (x: X) y f(y: Y) no podrían
convivir en la misma clase.
●
34
3.4 Genéricos
Pueden definirse clases genéricas que usen
parámetros. Estos parámetros genéricos aparecen
entre paréntesis.
●
class LIST [G]..●G es llamado parámetro formal genérico. En la
declaración, G representa un tipo arbitrario, por
tanto, una función podrá devolver un valor de tipo
G y una rutina usarlo como argumento.
item: G do ... end
put (x: G) do ... end
35
3.4 Genéricos
●
●
También es posible tener parámetros formales
limitados, para los que el parámetro actual debe
heredarse de una clase dada. Por ejemplo en
class HASH_TABLE [G, KEY -> HASHABLE]
una derivación HASH_TABLE [INTEGER,
STRING] sólo es válida si STRING hereda de
HASHABLE. Teniendo KEY limitada por
HASHABLE significa que para x: KEY podremos
aplicarle a x todos los métodos de HASHABLE.
36
3.5 Herencia
Para heredar de una o más clases, se debe incluir la
palabra reservada inherit al principio:
●
class C inherit
A
B
... Rest of class declaration ...
37
3.5 Herencia
●
Una clase puede sobrecargar alguno de los
features heredados. Esto debe aparecer
explícitamente en la declaración, usando la
palabra reservada redefine en la clausula de
herencia
class C inherit
A
redefine f, g, h end
B
redefine u, v end
38
3.6 Clases y métodos abstractos
Las clases pueden definirse como deferred class en lugar
de como class para indicar que esas clases no pueden ser
instanciadas. Es lo que en otros lenguajes se conoce como
clases abstractas.
●
Un método o feature puede ser igualmente abstracto
colocando la palabra deferred en lugar de una clausula do.
Si una clase tiene algún método deferred debe declararse
como tal, aunque también pueden hacerlo clases que no los
contengan.
●
39
3.7 Renombramiento
Cuando una clase hereda de una o más clases, toma todos
sus métodos con los nombres originales. Es posible en este
lenguaje renombrarlos haciendo uso de la palabra reservada
rename.
●
Esto es especialmente necesario en el caso de la herencia
múltiple, pues puede darse el caso de colisiones entre
métodos de distintas clases, lo cual violaría el principio de “no
sobrecarga” de nombres dentro del mismo método, devolviendo
un error.
●
40
3.8 Tuplas
El tipo tupla puede verse como una forma simple de
clase, dando solo atributos y el correspondiente
constructor. Un ejemplo típico sería:
●
TUPLE [name: STRING; peso: REAL; date: DATE]
y puede usar como una forma simple de descripción
cuando una clase no es necesaria. Una instancia de
una tupla es simplemente una secuencia de valores
entre parentesis
●
["Brigitte", 3.5, Anoche]
41
3.8 Tuplas
●
●
Los componentes de una tupla pueden accederse
como si fueran atributos de una clase, por ejemplo
si t ha sido asignado a la tupla, t.peso sería 3.5
La notación del punto también puede usarse para
asignar valores a una tupla
t.peso := t.peso + 0.5
●
Los nombres de atributos son opcionales, por tanto,
puede expresarse una tupla como TUPLE [A, B, C].
42
3.9 Bloques (agent)
●
Pueden ser utilizados para realizar iteraciones
Una_lista.do_all (agent acción)
Si queremos ejecutar las acciones solo para los
elementos que cumplen una condición
●
Una_lista.do_if (agent acción, agent condición)
43
3.9 Bloques (agent)
En los ejemplos anteriores, acción y condición son rutinas. Al
poner la palabra agent delante se llama automáticamente con
los parámetros adecuados.
●
Si deseamos llamar a una rutina cualquiera, podemos hacerlo
de 2 formas
●
●
a.call([args]) siendo a una rutina
●
Directamente a ([args])
Los argumentos se pasan como una tupla
●
44
3.10 Métodos “una sola vez”
(once routines)
Estos métodos realizan los cálculos una sola vez (en la
primera llamada), y las demás veces que se invocan devuelven
una referencia al resultado.
●
Para declarar estos métodos utilizaremos la palabra once en lugar
de do.
●
shared_object: SOME_TYPE
once
create Result.make (args)
-- This creates the object and returns a
reference to it through Result
end
45
3.11 Conversiones
Eiffel proporciona, al igual que otros muchos
lenguajes, mecanismos de conversión.
●
Simplemente generaliza los mecanismos de
conversión de la mayoría de los lenguajes de
programación, pudiéndose aplicar siempre que
los tipos sean compatibles.
●
46
3.11 Conversiones
●
Se puede realizar:
my_string := my_date
Convierte una fecha en un string.
create my_string.make_from_date (my_date)
Para realizar la conversión de la primera forma,
es necesario que haya un constructor
implementado para dicho fin, es decir, haber
implementado la segunda forma
●
47
3.12 Manejo de excepciones
●
Se realiza a nivel de procedimientos.
Si una operación falla en una rutina, la rutina
entera falla y se produce un error.
●
Si dicho error no lo maneja dicha rutina es
transferido a la rutina superior, así
sucesivamente hasta que, o bien se captura la
excepción, o llega el error al SO.
●
48
3.12 Manejo de excepciones
Para capturar las excepciones se utilizan los bloques
rescue. Éstos se ejecutan cuando se produce un fallo.
Son similares a los bloques try–catch de Java.
●
Se puede volver a probar a ejecutar la rutina que falló
después de realizar las operaciones de gestión del
error usando la palabra retry dentro del código del
bloque rescue (esto no existe en Java).
●
49
3.13 Concurrencia
Existen bibliotecas de hebras como
EiffelThreads y otras muchas, pero
que aún no forman parte de la
espcificación estándar oficial de Eiffel.
●
50
3.14 Operadores
La interpretación de una operación del tipo a+b es a.plus(b).
●
Para implementar un alias para una función se hace lo
siguiente:
●
<func> alias “<op>” (<param>:<tipo>):<tipo_devuleto>
---declaración normal de función--end
51
3.14 Operadores
Existen también operadores libres que se pueden
utilizar para definir sintaxis infija o prefija, por
ejemplo para aplicaciones matemáticas o fijas.
●
Cada clase puede tener, además, una función
asociada con el operador ‘[]’ para poder utilizar la
notación a[i] en las clases que tengan estructura
similar a un array (vectores, matrices, …).
●
52
3.15 Léxico y sintaxis
Eiffel no es sensible a las mayúsculas
●
Los comentarios de linea se indican con - -
●
El separador de instrucciones (;) se suele omitir, salvo para
separar instrucciones en la misma línea
●
Es usual agrupar los métodos con características similares
para una mayor legibilidad
●
class <nombre> inherit <clases>
feature
--declaraciones
...
end
53
3.15 Interfaces para otras
herramientas y lenguajes
Eiffel, a pesar de ser un L.O.O., posee una
arquitectura abierta para interaccionar con
software externo.
●
Proporciona un interfaz directo con C/C++. La
mayoría de los compiladores de Eiffel utilizan C
como lenguaje intermedio.
●
Las últimas versiones del compilador SmartEiffel
ofrcen también la posibilidad de generar bytecode
de Java
54
●
Descargar