programación 3

Page 1

Programación Avanzada en C++ L. Hernández

2008 © Luis Hernández

Programación en Ingeniería Electrónica | Programacion Avanzada en C++

1


Programación Orientada a Objetos

2008 © Luis Hernández

Programación en Ingeniería Electrónica | Programacion Avanzada en C++

2


Nuevas incorporaciones desde C  Espacio de utilización de una variable:  

se puede declarar variables en cualquier parte del programa. variables globales

 Acceso a variables ocultas.

2008 © Luis Hernández

Programación en Ingeniería Electrónica | Programacion Avanzada en C++

3


Nuevas incorporaciones desde C  Referencias 

Nombre alternativo para una variable u objeto int i=1; int &x=i;

  

Las variables x e i se refieren al mismo espacio de memoria. Se tienen que inicializar siempre. Se utilizan en pase de parámetros a funciones donde se quiera modificar su contenido.

 Memoria dinámica:  

new tipo[tamaño]; delete [] puntero;

2008 © Luis Hernández

Programación en Ingeniería Electrónica | Programacion Avanzada en C++

4


Nuevas incorporaciones desde C  Declaraciones de funciones  

Parámetros con valor por defecto. En funciones con varios parámetros:

• si el parámetro k-1 está definido por defecto, el parámetro k también tiene que estarlo.

Pase de parámetros por referencia.

2008 © Luis Hernández

Programación en Ingeniería Electrónica | Programacion Avanzada en C++

5


Nuevas incorporaciones desde C  Operadores E/S:    

operador extracción: >> operador inserción: << Stream de entrada estándar: cin Stream de salida estándar: cout

2008 © Luis Hernández

Programación en Ingeniería Electrónica | Programacion Avanzada en C++

6


Evolución hacia la POO  Objetivos de la evolución:   

Menor interconexión entre las partes de un programa. Ocultación de la información. Abstracción: • que los componentes del S.W. sean lo más cercano posible a las ideas que componen el problema.

Re-utilización del código.

 Todos estos objetivos están relacionados, pero la piedra angular es la ocultación de la información.

2008 © Luis Hernández

Programación en Ingeniería Electrónica | Programacion Avanzada en C++

7


Programación con procedimientos  El programa se divide en dos partes:  

Algoritmos Datos

 La parte algorítmica se estructura en procedimientos.  Beneficios:   

Abstracción de operaciones. Extensión del lenguaje. Re-utilización del código.

 Inconvenientes:  

No existe una clara estructuración de los datos que los relacione con los procedimientos que los manejan. Indefensión ante varios problemas: • No se garantiza el correcto estado de las estructuras de información. • No hay independencia de representación.

2008 © Luis Hernández

Programación en Ingeniería Electrónica | Programacion Avanzada en C++

8


FIFO: Programación con procedimientos  No hay nada que impida que un programador haga un mal uso de los datos. 

Ejemplo: confundir el uso de cola y cabeza.

 No es posible garantizar que la cola se encuentra en un estado correcto.  ¿Que sucede si un día queremos cambiar la estructura de los datos? 

Ejemplo: cambiar el vector de la cola por una lista enlazada. • Tendría que re-escribir el programa.

 Realmente,¿qué parte del código es re-utilizable?.

2008 © Luis Hernández

Programación en Ingeniería Electrónica | Programacion Avanzada en C++

9


FIFO: Ocultación de la información  Cierta parte de los datos y funciones sólo será accesible desde ciertas funciones.  Si el interfaz está bien definido, el estado de la cola siempre es correcto.  Si se cambia la estructura interna de los datos sólo hay que cambiar las funciones del interfaz.  Re-utilización del código. Se aprovecha:  

la estructura de datos las funciones que la manejan

 Ocultación de la información = Encapsulamiento de los datos

2008 © Luis Hernández

Programación en Ingeniería Electrónica | Programacion Avanzada en C++

10


Formas de ocultación de la información  Módulos (Programación modular)   

Las funciones (procedimientos) y datos se agrupan en diferentes ficheros (módulos). Para cada módulo se definen los procedimientos y datos que se exportan. Sólo se puede acceder desde fuera del módulo a aquella parte que ha sido exportada.

 Objetos (Programación orientada a objetos)

 Un módulo se compone de dos partes:  

2008 © Luis Hernández

definición → Interfaz implementación → Código de la interfaz y de la parte oculta.

Programación en Ingeniería Electrónica | Programacion Avanzada en C++

11


Programación modular  Aportaciones de la modularidad    

Descomposición de un problema complejo en módulos más simples. Re-utilización de los módulos existentes para desarrollar nuevo software. Independencia de la implementación. Ocultación de la información.

 Limitaciones de la modularidad 

Ejemplo: Sólo puedo tener una cola en mi programa.

2008 © Luis Hernández

Programación en Ingeniería Electrónica | Programacion Avanzada en C++

12


Programación orientada a objetos  Los objetos son entidades que agrupan datos y procedimientos que operan sobre esos datos.  

modulo ≈ fichero objeto ≈ variable

 Los objetos se caracterizan por tres propiedades:   

Estado Operaciones Identidad dentro del programa (=instanciación)

 Una clase es la descripción de un conjunto de objetos similares.  Los objetos son instancias de una clase. 

Ejemplo: podemos definir la clase matriz y a partir de ella los objetos matriz1 y matriz2.

2008 © Luis Hernández

Programación en Ingeniería Electrónica | Programacion Avanzada en C++

13


Clases y objetos  Clase: 

Abstracción de un conjunto de objetos caracterizados por las mismas propiedades y los mismos comportamientos.

 Objeto: 

Abstracción capaz de responder a una petición del servicio de mensaje.

 Un objeto es una instancia de una clase.  La clase contiene su comportamiento y sus propiedades.  El objeto puede crearse dinámicamente en el transcurso de la ejecución de un programa. 2008 © Luis Hernández

Programación en Ingeniería Electrónica | Programacion Avanzada en C++

14


Objetos

 El mensaje es el único medio de comunicación entre los objetos.  

Consiste en una petición explícita de una operación que debe realizar el objeto Puede ser asociado a una llamada de procedimiento

2008 © Luis Hernández

Programación en Ingeniería Electrónica | Programacion Avanzada en C++

15


El concepto de objeto  Objeto: Entidad de programación con componentes de dos tipos:  

Estado: Datos Comportamiento: Procedimientos que manipulan los datos con exclusividad.

 Cada objeto posee un interfaz que contiene los servicios que oferta al exterior.

2008 © Luis Hernández

Programación en Ingeniería Electrónica | Programacion Avanzada en C++

16


Programación orientada a objetos  Acceso convencional vs OO  Comunicación entre objetos: 

Un objeto pide un servicio a otro por medio de un mensaje: destinatario + operación + argumentos

2008 © Luis Hernández

Programación en Ingeniería Electrónica | Programacion Avanzada en C++

17


Globalidad vs Localidad  Programación modular 

Aquí los datos son globales, son accesibles desde todos los procedimientos.

 Programación por objetos:  

Aquí los datos son locales a cada objeto. Sólo son accesibles para los procedimientos (operaciones) definidos en el objeto.

2008 © Luis Hernández

Programación en Ingeniería Electrónica | Programacion Avanzada en C++

18


Clases y objetos  Clase 

vehiculo

 Campos    

velocidad nombre precio cantidad

 Métodos    

precioConIVA: devolver (1,16*precio) darVelocidad: devolver (velocidad) retirar(c): cantidad ← cantidad ­ c añadir(c): cantidad ← cantidad + c

2008 © Luis Hernández

Programación en Ingeniería Electrónica | Programacion Avanzada en C++

19


Declaración de clases  Declaración de la clase  Definición de las funciones de la clase  Instanciación de la clase

2008 © Luis Hernández

Programación en Ingeniería Electrónica | Programacion Avanzada en C++

20


Programa ejemplo: Pila

2008 © Luis Hernández

Programación en Ingeniería Electrónica | Programacion Avanzada en C++

21


Programa ejemplo: Pila

2008 © Luis Hernández

Programación en Ingeniería Electrónica | Programacion Avanzada en C++

22


Constructores y destructores  Constructor 

Función miembro de la clase que se ejecuta cuando se crea un objeto. Podemos tener varios constructores en una clase, pero han de diferir en los parámetros.

2008 © Luis Hernández

 Destructor 

Función miembro de la clase que se ejecuta al final de la vida de cada objeto.

Programación en Ingeniería Electrónica | Programacion Avanzada en C++

23


Utilización de constructores

 Utilización de constructores:   

Sin parámetros: A a; Con un parámetro: A a(5); ó A a=5; Con varios parámetros: A a(5,3);

 Constructores por defecto: 

Constructor copia:

• Crea un objeto b2 donde los datos de b2 serán iguales a los de b1. • Aunque no se defina el constructor copia, éste existe para que se puedan pasar objetos como parámetros por valor.

Constructor sin parámetros:

• Aunque no se defina, éste existe para que se puedan definir objetos de la clase (no ejecuta nada).

2008 © Luis Hernández

Programación en Ingeniería Electrónica | Programacion Avanzada en C++

24


Utilización de constructores  Desaparición de constructores por defecto: 

Constructor sin parámetros:

• Desaparece cuando definimos cualquier otro constructor.

Constructor copia:

• Desaparece cuando definimos un nuevo constructor copia. • Siempre hay un constructor copia, y solo uno, en cada clase.

2008 © Luis Hernández

Programación en Ingeniería Electrónica | Programacion Avanzada en C++

25


Constructor copia  Definición  Utilización

2008 © Luis Hernández

Programación en Ingeniería Electrónica | Programacion Avanzada en C++

26


Clases compuestas

 Una clase donde algún dato miembro es un objeto de otra clase.  ¿Cuál es el orden de construcción? 2008 © Luis Hernández

Programación en Ingeniería Electrónica | Programacion Avanzada en C++

27


Expansión inline  Evitar llamadas a funciones.  El compilador simula el pase de parámetros.

2008 © Luis Hernández

Programación en Ingeniería Electrónica | Programacion Avanzada en C++

28


Clases y funciones friend  Funciones friend: 

Una función ajena a la clase pueda acceder a la parte privada de la clase.

 Clases friend: 

Todos los métodos de una clase puedan acceder a la parte privada de otra clase.

2008 © Luis Hernández

Programación en Ingeniería Electrónica | Programacion Avanzada en C++

29


Calificación de variables miembro  Distinguir entre:  

variables miembro de una clase otro tipo de variables.

 Operador resolución de ámbito “::”

2008 © Luis Hernández

Programación en Ingeniería Electrónica | Programacion Avanzada en C++

30


Palabra reservada this

 Representa un puntero al objeto que recibe la llamada.  Todos los objetos de todas las clases tienen this como dato miembro. 2008 © Luis Hernández

Programación en Ingeniería Electrónica | Programacion Avanzada en C++

31


Variables de clase e instancia  Variables de clase: 

común a todos los objetos (instancias) de una clase.

 Variables de instancia: 

propio de cada objeto (instancia) de la clase.

2008 © Luis Hernández

Programación en Ingeniería Electrónica | Programacion Avanzada en C++

32


Variables de clase e instancia

2008 © Luis Hernández

Programación en Ingeniería Electrónica | Programacion Avanzada en C++

33


Funciones de clase  Funciones de clase:  

Actúan sobre variables de clase. Sólo pueden actuar sobre las variables de instancia de la propia clase cuando pertenecen a un objeto: • pasado como parámetro. • declarado dentro de la propia función.

2008 © Luis Hernández

Programación en Ingeniería Electrónica | Programacion Avanzada en C++

34


Punteros a objetos  Declaración de punteros a objetos de una clase.  Utilización del operador new y delete:  

Al ejecutarse el operador new, se llama al constructor de la clase automáticamente (malloc no lo hace). delete llama al destructor (free no).

2008 © Luis Hernández

Programación en Ingeniería Electrónica | Programacion Avanzada en C++

35


Ejemplo de vectores y punteros a objetos

2008 © Luis Hernández

Programación en Ingeniería Electrónica | Programacion Avanzada en C++

36


Herencia

2008 © Luis Hernández

Programación en Ingeniería Electrónica | Programacion Avanzada en C++

37


Herencia  Definir una nueva clase:  

como extensión de otra previamente definida. sin modificar la ya existente.

 La nueva clase hereda de la clase anterior:  

las variables. las operaciones .

 Principal objetivo/ventaja: 

Reutilización del código.

• Ahorro de esfuerzo. • Mayor confianza en el código.

2008 © Luis Hernández

Programación en Ingeniería Electrónica | Programacion Avanzada en C++

38


Organización jerárquica

2008 © Luis Hernández

Programación en Ingeniería Electrónica | Programacion Avanzada en C++

39


Herencia en POO  Una función recibe un objeto de la clase base. void Despedir (empleado);

 Una función puede recibir objetos de la clase base y también de sus derivadas. empleado e; empleado_producción ep; empleado_comerciales ec; Despedir (e); Despedir (ep); Despedir (ec);

2008 © Luis Hernández

Programación en Ingeniería Electrónica | Programacion Avanzada en C++

40


Herencia de métodos y variables  Las clases derivadas reciben (=heredan) las variables y métodos de la clase base. Empleado_comercial ec; Empleado_produccion ep; ec.Cambiar_Sueldo(); ep.Cambiar_Sueldo();

2008 © Luis Hernández

Programación en Ingeniería Electrónica | Programacion Avanzada en C++

41


Composición y herencia  Composición: 

Relación tener-un

 Herencia: 

Un coche tiene un motor 

Contener un objeto.

2008 © Luis Hernández

Relación ser-un Un coche es un vehículo

Contener una clase.

Programación en Ingeniería Electrónica | Programacion Avanzada en C++

42


Ejemplos de composición y herencia  Clase persona y clase empleado. 

Herencia: un empleado es una persona.

 Clase persona y clase domicilio. 

Composición: una persona tiene un domicilio.

 Clase lista y clase nodo de la lista: 

Composición: una lista tiene un puntero de tipo nodo al nodo que está en cabeza de la lista (tener-un).

 Clase empresa, clase empleado y clase jefe de grupo de empleados. 

Herencia entre empleado y jefe. • Un jefe es un empleado.

Composición entre empresa y empleado o jefe.

• Una empresa puede tener una lista de empleados y otra de jefes. • Por el principio de los subtipos, una empresa puede tener una única lista donde aparezcan tanto jefes como empleados.

2008 © Luis Hernández

Programación en Ingeniería Electrónica | Programacion Avanzada en C++

43


Ejemplo de herencia

2008 © Luis Hernández

Programación en Ingeniería Electrónica | Programacion Avanzada en C++

44


Ejemplo de herencia  Los miembros de la clase empleado se pueden utilizar en las clases derivadas tal y como si hubiesen sido definidos en éstas

2008 © Luis Hernández

Programación en Ingeniería Electrónica | Programacion Avanzada en C++

45


Modos de acceso  private 

Lo que es “private” en la clase base no es accesible en la clase derivada.

 public 

Lo que definimos como “public” es accesible desde cualquier parte.

 protected 

Lo que definimos como “protected” en la clase base: • es accesible en la clases derivadas • no es accesible fuera de las clases derivadas o base.

2008 © Luis Hernández

Programación en Ingeniería Electrónica | Programacion Avanzada en C++

46


 public 

Tipos de herencia

los modos de acceso a los miembros de la clase base se quedan igual en la clase derivada.

 protected 

los miembros “public” de la clase base pasan a ser “protected”, el resto se queda igual.

 private 

todos los miembros de la clase base pasan a ser “private” en la derivada.

2008 © Luis Hernández

Programación en Ingeniería Electrónica | Programacion Avanzada en C++

47


Redefinición de miembros

 A veces, interesa cambiar en la subclase la definición de algo que está en la clase base.  Lo redefinido no desaparece. 2008 © Luis Hernández

Programación en Ingeniería Electrónica | Programacion Avanzada en C++

48


Ejemplo de redefinición de miembros

2008 © Luis Hernández

Programación en Ingeniería Electrónica | Programacion Avanzada en C++

49


Herencia múltiple  Una clase derivada hereda las características de más de una clase base.

2008 © Luis Hernández

Programación en Ingeniería Electrónica | Programacion Avanzada en C++

50


Constructores y destructores  Construcción objeto clase derivada: 

Primero se construye la parte heredada de la clase(s) base. • Se ejecutan los constructores de las clases base.

Por último se ejecuta el código del constructor de la clase derivada.

 Destrucción objeto clase derivada: 

El proceso es a la inversa que en la construcción.

• Se ejecuta primero el destructor de la clase derivada y a continuación los de las clases base.

2008 © Luis Hernández

Programación en Ingeniería Electrónica | Programacion Avanzada en C++

51


Ejemplo de constructores y destructores  Constructores y destructores en la herencia

2008 © Luis Hernández

Programación en Ingeniería Electrónica | Programacion Avanzada en C++

52


Ejemplo de constructores y destructores  Constructores y destructores en clases compuestas y derivadas.

2008 © Luis Hernández

Programación en Ingeniería Electrónica | Programacion Avanzada en C++

53


Ejemplo de constructores y destructores  Llamadas a los constructores de las clases base.

2008 © Luis Hernández

Programación en Ingeniería Electrónica | Programacion Avanzada en C++

54


Ejemplo de constructores y destructores

2008 © Luis Hernández

Programación en Ingeniería Electrónica | Programacion Avanzada en C++

55


Ejemplo de constructores y destructores

2008 © Luis Hernández

Programación en Ingeniería Electrónica | Programacion Avanzada en C++

56


Clase base virtual

2008 © Luis Hernández

Programación en Ingeniería Electrónica | Programacion Avanzada en C++

57


Herencia virtual  Si una clase base virtual define constructores, debe proporcionar uno de estos dos constructores:  

un constructor sin parámetros un constructor que admita valores por defecto para todos los parámetros.

 Las clases derivadas de una clase base virtual tienen que ser definidas como herencia virtual.

2008 © Luis Hernández

Programación en Ingeniería Electrónica | Programacion Avanzada en C++

58


Ejemplo de Herencia virtual

2008 © Luis Hernández

Programación en Ingeniería Electrónica | Programacion Avanzada en C++

59


Punteros a clases derivadas

2008 © Luis Hernández

Programación en Ingeniería Electrónica | Programacion Avanzada en C++

60


Polimorfismo

2008 © Luis Hernández

Programación en Ingeniería Electrónica | Programacion Avanzada en C++

61


Polimorfismo  El polimorfismo se refiere al hecho de que una misma función adopte múltiples formas.  Esto se consigue por medio de la sobrecarga: 

Sobrecarga de funciones:

• un mismo nombre de función para distintas funciones.

a = Sumar(c,d); a = Sumar(c);

Sobrecarga de operadores:

• un mismo operador con distintas funcionalidades. • Ejemplo: Sobrecargar el operador + sobre la clase cadena para que permita concatenar dos de estos objetos: entero1 = entero2 + 5; cadena1 = cadena2 + cadena3;

2008 © Luis Hernández

Programación en Ingeniería Electrónica | Programacion Avanzada en C++

62


Sobrecarga de constructores  Solo en caso de que no definamos ningún constructor, tenemos el constructor por defecto.

2008 © Luis Hernández

Programación en Ingeniería Electrónica | Programacion Avanzada en C++

63


Sobrecarga de funciones

 Tenemos 2 funciones costructor string().  Tenemos 4 posibles llamadas a 4 funciones diferentes strcmp():  

3 en la clase. 1 en la librería “string.h” de C.

 Tenemos 2 funciones strcpy() en la clase.

2008 © Luis Hernández

Programación en Ingeniería Electrónica | Programacion Avanzada en C++

64


Sobrecarga de funciones  En la sobrecarga de funciones se desarrollan distintas funciones con un mismo nombre pero distinto código.  Las funciones que comparten un mismo nombre deben tener una relación en cuanto a su funcionalidad.  Aunque comparten el mismo nombre, deben tener distintos parámetros de manera que el compilador pueda distinguir entre las distintas funciones cuando encuentra una llamada. Éstos pueden diferir en :   

número tipo orden

 El tipo del valor de retorno de una función no es válido como distinción. 

Esto es debido a que ese valor en C++ no es necesario que sea recogido por otro objeto.

2008 © Luis Hernández

Programación en Ingeniería Electrónica | Programacion Avanzada en C++

65


Ejemplo de sobrecarga de funciones

2008 © Luis Hernández

Programación en Ingeniería Electrónica | Programacion Avanzada en C++

66


Sobrecarga de operadores  Consiste en definir nuevas funcionalidades para los operadores definidos en el lenguaje.  Se pueden sobrecargar prácticamente todos los operadores del lenguaje:  

No podemos inventar nuevos operadores. No podemos re-definir funcionalidades de los operadores que ya están definidas

2008 © Luis Hernández

Programación en Ingeniería Electrónica | Programacion Avanzada en C++

67


Sobrecarga de operadores  Al menos uno de los operandos del operador sobrecargado debe ser una clase definida por nosotros  La sobrecarga de operadores es un caso particular de la sobrecarga de funciones:  

el operando de la izquierda puede pasar a ser el propietario de la función, o bien el primer argumento de la función.

2008 © Luis Hernández

Programación en Ingeniería Electrónica | Programacion Avanzada en C++

68


Sobrecarga de operadores

2008 © Luis Hernández

Programación en Ingeniería Electrónica | Programacion Avanzada en C++

69


Sobrecarga de operadores  Para cualquier clase que se defina, el compilador define el operador asignación “=“.  Cuando no me sirve, debo re-definirlo.

2008 © Luis Hernández

Programación en Ingeniería Electrónica | Programacion Avanzada en C++

70


Operador incremento y decremento  Tiene dos posibles notaciones:  

prefija: ++a postfija: a++

2008 © Luis Hernández

Programación en Ingeniería Electrónica | Programacion Avanzada en C++

71


Operador subíndice  Devolución de una referencia: 

Se debe devolver una referencia cuando queremos que se pueda modificar el propio objeto que se devuelve.

2008 © Luis Hernández

Programación en Ingeniería Electrónica | Programacion Avanzada en C++

72


Operador subíndice  Ejemplo de utilización de índices dobles.

2008 © Luis Hernández

Programación en Ingeniería Electrónica | Programacion Avanzada en C++

73


Conversión de clases  Un constructor de Y que reciba X permite al compilador convertir objetos de la clase X en objetos de la clase Y.

2008 © Luis Hernández

Programación en Ingeniería Electrónica | Programacion Avanzada en C++

74


Operadores de conversión  Los constructores de una clase X: 

permiten definir qué otras clases pueden ser convertidas en la clase X.

 Los operadores de conversión que se definen en una clase X: 

permiten definir en qué otras clases se pueden convertir la clase x.

2008 © Luis Hernández

Programación en Ingeniería Electrónica | Programacion Avanzada en C++

75


Operadores de conversión

2008 © Luis Hernández

Programación en Ingeniería Electrónica | Programacion Avanzada en C++

76


Ligadura dinámica  Funciones virtuales: 

Son una clase de sobrecarga de funciones, pero con la diferencia de: • Sobrecarga de funciones: se decide que función se va a ejecutar en tiempo de compilación. • Funciones virtuales: se decide en tiempo de ejecución (poliformismo en tiempo de ejecución).

2008 © Luis Hernández

Programación en Ingeniería Electrónica | Programacion Avanzada en C++

77


Ligadura dinámica

 Se ejecutará la función muestra() de alumno o de profesor dependiendo de la clase de objeto a la que apunte p (ligadura dinámica, en tiempo de ejecución).  La función persona::muestra() no se ejecuta porque es virtual y ha sido substituida en cada clase derivada.  Si no se hubiera definido como virtual la función muestra() en la clase persona se ejecutaría siempre persona::muestra() 2008 © Luis Hernández

Programación en Ingeniería Electrónica | Programacion Avanzada en C++

78


Funciones virtuales  Cuando se define una función virtual: 

El prototipo debe ser el mismo en las clases base y derivadas.

 Una función definida como virtual en una clase base:  

es virtual en todas sus clases derivadas, sea cual sea el nivel de derivación. Puede ser re-definida o no en las clases derivada.

2008 © Luis Hernández

Programación en Ingeniería Electrónica | Programacion Avanzada en C++

79


Clases abstractas  No tiene mucho sentido:  

definir código a la función figura:area() existan objetos de la clase figura

 Solución: Podemos definir la clase figura como una clase abstracta.

2008 © Luis Hernández

Programación en Ingeniería Electrónica | Programacion Avanzada en C++

80


Clases abstractas  Funciones virtuales puras: 

Las clases derivadas están obligadas a re-definirla.

2008 © Luis Hernández

Programación en Ingeniería Electrónica | Programacion Avanzada en C++

81


Destructor virtual

2008 © Luis Hernández

Programación en Ingeniería Electrónica | Programacion Avanzada en C++

82


Turn static files into dynamic content formats.

Create a flipbook
Issuu converts static files into: digital portfolios, online yearbooks, online catalogs, digital photo albums and more. Sign up and create your flipbook.