Algoritmos y estructuras de datos. Concepto de tipo de datos abstracto

Un tipo de datos describe un conjunto de objetos con propiedades similares. Todos los lenguajes de programación tradicionales utilizan un conjunto de tipos de datos básicos (real, entero, cadena, carácter). Los tipos de datos básicos están sujetos a un conjunto predefinido de operaciones. Por ejemplo, el tipo de datos básico entero le permite realizar operaciones como suma, resta, multiplicación y división.

Los lenguajes de programación tradicionales incluyen constructores de tipos, el más común de los cuales es el constructor de registros. Por ejemplo, para un registro de tipo CLIENTE, puede definir campos de datos. El registro CLIENTE será un nuevo tipo de datos que almacenará información del cliente; puede acceder directamente a esta estructura de datos haciendo referencia a los nombres de los campos. Puede realizar operaciones en un registro como ESCRIBIR, LEER, ELIMINAR, ACTUALIZAR. No se pueden definir nuevas operaciones para tipos de datos básicos.

Al igual que los tipos de datos básicos, los tipos de datos abstractos (ATD) describen muchos objetos similares. Existen diferencias entre ATD y el tipo de datos tradicional:

· las operaciones bajo ATD son definidas por el usuario;

· Los ATD no permiten el acceso directo a la representación de datos internos ni a la implementación del método.

Algunos sistemas orientados a objetos (como Smalltalk) implementan tipos de datos básicos como abstractos.

Para crear un tipo de datos abstractos debe proporcionar:

· escriba el nombre;

· representación de datos o variables de instancia de un objeto propiedad de ATD; cada variable de instancia tiene un tipo de datos, que puede ser un tipo base u otro ATD;

· las operaciones bajo ATD y restricciones se implementan utilizando métodos.

La definición de ATD reconstruye la definición de clase. Algunos sistemas orientados a objetos utilizan la palabra clave type para distinguir entre clases y tipos cuando se refieren a estructuras de datos y métodos de una clase, y la palabra clave class cuando se refieren a un conjunto de instancias de un objeto. El tipo es un concepto más estático, mientras que la clase se ocupa principalmente del tiempo de ejecución. La diferencia entre una clase OO y un tipo OO se puede ilustrar con un ejemplo. Digamos que tenemos una plantilla para un constructor. La plantilla va acompañada de una descripción de su estructura, así como de instrucciones para su uso. Esta plantilla es la definición de tipo. Un conjunto de productos reales elaborados utilizando una plantilla, cada uno de los cuales tiene un número único (u OID), constituye una clase.

ATD junto con la herencia le permiten crear objetos complejos. Un objeto complejo está formado por una combinación de otros objetos que mantienen relaciones complejas entre sí. Un ejemplo de objeto complejo lo podemos encontrar en los sistemas de seguridad donde se utilizan diferentes tipos de datos:

1. datos estándar (tabulares) sobre el empleado (nombre completo, número de tabla, etc.);

2. mapa de bits para almacenar la fotografía de un empleado;

La capacidad de trabajar con un entorno de datos tan complejo con relativa facilidad aumenta la importancia de los sistemas orientados a objetos en el mercado actual de bases de datos.

Ministerio de Educación y Ciencia de la Federación de Rusia

Institución educativa presupuestaria del estado federal

educación profesional superior

UNIVERSIDAD NACIONAL DE INVESTIGACIÓN NUCLEAR "MEPhI"

Instituto Dimitrovgrad de Ingeniería y Tecnología

Departamento Tecnologías de la información

admitir a la defensa "" 2012

Cabeza departamento Rakova O.A.

Trabajo de curso

por disciplina"Programación orientada a objetos"

Sujeto:"Tipos de datos abstractos. Liza"

Completado por: estudiante gr. VT-31

Shayakov A.F.

Jefe: Arte. profesor del departamento de informática

Alenin V. A.

Controlador de normas: art. profesor del departamento de informática

Alenin V. A.

Calificación:

Fecha de defensa:

Dimitrovgrado, 2012

Ministerio de Educación y Ciencia de la Federación de Rusia

Institución educativa presupuestaria del estado federal

educación profesional superior

UNIVERSIDAD NACIONAL DE INVESTIGACIÓN NUCLEAR "MEPhI"

Instituto Dimitrovgrad de Ingeniería y Tecnología

para el trabajo del curso

Disciplina: programación orientada a objetos

Tema: Tipos de datos abstractos.

Liza

Intérprete: Shayakov A.F.

Responsable: Alenin V.A.

1.Parte teórica:

2.Parte práctica:

Escriba un programa en C++ con una estructura orientada a objetos para implementar listas lineales enlazadas individualmente.

Plazos previstos para la finalización de la obra:

    Parte teórica - 15% para la semana 5

    Parte práctica – 80% para la semana 7

    Sección experimental: ____% por ____ semana

    Protección – 100% para la semana 10

Requisitos de diseño:

    El cálculo y nota explicativa del trabajo de curso deberá presentarse en formato electrónico e impreso;

    El volumen del informe debe tener al menos 20 páginas mecanografiadas sin incluir los archivos adjuntos.

    El RPP está firmado por el responsable del control estándar.

Responsable de obra _________________

Intérprete _________________________________

Fecha de emisión "_____" ___________ 2012

SHAYAKOV A.F. TEMA: TIPOS DE DATOS ABSTRACTOS. LISTAS, Trabajos de curso / DITI, No. 230105.65-Dimitrovgrad, 2012. - 29 páginas, fig. 11, babero. nombre 10, aplicaciones 1.

Palabras clave: listas lineales enlazadas individualmente, C++, programación orientada a objetos.

El objeto de estudio son las listas lineales enlazadas individualmente.

El objetivo del trabajo es estudiar listas lineales enlazadas individualmente y escribir un programa en C++ con una estructura orientada a objetos para su implementación.

Conclusiones: en este trabajo se estudiaron en profundidad las listas lineales enlazadas individualmente, así como los métodos para su representación en memoria.

El programa, escrito en C++, cumple totalmente con la estructura orientada a objetos, realiza de manera correcta y eficiente su tarea principal: implementar listas lineales enlazadas individualmente.

Introducción 6

1 Parte teórica 7

1.1 Tipos de datos abstractos. Listas lineales 7

1.2 Concepto de programación orientada a objetos 8

2 Parte práctica 15

3 Pruebas 23

Conclusión 25

Referencias 26

Apéndice A 27

Introducción

A menudo, cuando se trabaja con datos, es imposible determinar cuánta memoria se necesitará para almacenarlos; la memoria debe asignarse durante la ejecución del programa según sea necesario en bloques separados. Los bloques están vinculados entre sí mediante punteros.

Las estructuras dinámicas también se utilizan ampliamente para trabajar de manera más eficiente con datos cuyo tamaño se conoce, especialmente para resolver problemas de clasificación.

Un elemento de cualquier estructura dinámica consta de dos partes: información, para cuyo almacenamiento se crea la estructura, y punteros, que aseguran la conexión de los elementos entre sí.

  1. parte teorica

1.1Tipos de datos abstractos. Listas lineales

El concepto de tipos de datos abstractos es clave en programación. La abstracción implica separación y consideración independiente de la interfaz y la implementación.

La abstracción de datos implica definir y considerar tipos de datos abstractos (ADT) o, de manera equivalente, nuevos tipos de datos ingresados ​​por el usuario.

Un tipo de datos abstracto es una colección de datos junto con un conjunto de operaciones que se pueden realizar con esos datos.

Listas lineales

En una lista lineal, cada elemento está relacionado con el siguiente y posiblemente con el anterior.

En el primer caso, la lista se llama simplemente enlazada, en el segundo, doblemente enlazada.

Si conecta el último elemento con un puntero al primero, obtendrá una lista circular.

    Cada elemento de la lista contiene una clave que identifica ese elemento. La clave suele ser un número entero o una cadena y forma parte del campo de datos.

    Cuando se trabaja con una lista, diferentes partes del campo de datos pueden actuar como clave. Las claves de diferentes elementos de la lista pueden ser las mismas.

    Puede realizar las siguientes operaciones en listas:

    formación inicial de la lista (creación del primer elemento);

    agregar un elemento al final de la lista;

    leer un elemento con una clave determinada;

insertar un elemento en una ubicación específica de la lista (antes o después de un elemento con una clave determinada);

eliminar un elemento con una clave determinada;

ordenar la lista por clave.

La metodología orientada a objetos, al igual que la metodología estructural, fue creada con el objetivo de disciplinar el proceso de desarrollo de grandes sistemas de software y así reducir su complejidad y costo.

Una metodología orientada a objetos tiene los mismos objetivos que una metodología estructural, pero los aborda desde un punto de partida diferente y, en la mayoría de los casos, permite gestionar proyectos más complejos que una metodología estructural.

Como sabes, uno de los principios de la gestión de la complejidad de los proyectos es la descomposición.

Gradi Booch distingue dos tipos de descomposición: algorítmica (como él llama descomposición apoyada por métodos estructurales) y orientada a objetos, cuya diferencia, en su opinión, es la siguiente: “La división por algoritmos concentra la atención en el orden de los eventos que ocurren , y la división por objetos da especial importancia a los factores que causan acciones o son objetos de aplicación de estas acciones”.

En otras palabras, la descomposición algorítmica tiene más en cuenta la estructura de las relaciones entre partes de un problema complejo, mientras que la descomposición orientada a objetos presta más atención a la naturaleza de las relaciones.

En la práctica, se recomienda utilizar ambos tipos de descomposición: al crear proyectos grandes, es recomendable utilizar primero un enfoque orientado a objetos para crear una jerarquía general de objetos que reflejen la esencia de la tarea programable y luego utilizar la descomposición algorítmica. en módulos para simplificar el desarrollo y mantenimiento del paquete de software.

La programación OO es sin duda una de las áreas más interesantes para el desarrollo de programas profesionales.

Objetos y clases

Un objeto es parte de la realidad que nos rodea, es decir, existe en el tiempo y el espacio (el concepto de objeto en programación se introdujo por primera vez en el lenguaje Simula). Formalmente, el objeto es bastante difícil de definir. Esto se puede hacer a través de algunas propiedades, a saber: el objeto tiene estado, comportamiento y puede identificarse de forma única (en otras palabras, tiene un nombre único).

Una clase es un conjunto de objetos que tienen una estructura común y un comportamiento común. Una clase es una descripción (abstracción) que muestra cómo construir una variable de esta clase que existe en el tiempo y el espacio, llamada objeto. El significado de las oraciones “descripción de variables de clase” y “descripción de objetos de clase” es el mismo.

Un objeto tiene estado, comportamiento y pasaporte (un medio para su identificación única); la estructura y el comportamiento de los objetos se describen en las clases de las que son variables.

Definamos ahora los conceptos de estado, comportamiento e identificación de un objeto.

El estado de un objeto combina todos sus campos de datos (componente estático, es decir, que no cambia) y los valores actuales de cada uno de estos campos (componente dinámico, es decir, que suele cambiar).

El comportamiento expresa la dinámica de los cambios en los estados de un objeto y su reacción a los mensajes entrantes, es decir. cómo un objeto cambia sus estados e interactúa con otros objetos.

La identificación (reconocimiento) de un objeto es una propiedad que le permite distinguir un objeto de otros objetos de la misma o de otras clases. La identificación se realiza mediante un nombre único (pasaporte), que se asigna a un objeto en el programa, como cualquier otra variable.

Ya se dijo anteriormente que el enfoque procedimental (y también modular) permite crear programas que constan de un conjunto de procedimientos (subrutinas) que implementan algoritmos determinados. Por otro lado, el enfoque orientado a objetos representa los programas como un conjunto de objetos que interactúan entre sí. Los objetos interactúan a través de mensajes.

Supongamos que nuestro objeto es un círculo. Entonces el mensaje enviado a este objeto podría ser: "dibújate a ti mismo". Cuando decimos que se envía un mensaje a un objeto, en realidad estamos llamando a alguna función de este objeto (componente de función). Entonces, en el ejemplo anterior, llamaremos a una función que dibujará un círculo en la pantalla.

La encapsulación es uno de los principios fundamentales de la programación orientada a objetos, cuya idea es que todas las propiedades y métodos se combinen dentro de un objeto.

El nombre mismo del término "encapsulación" proviene de la palabra inglesa encapsulate, que literalmente significa "sellar en una cápsula" o "cubrir con una cáscara". Por tanto, un objeto (cápsula) contiene métodos y propiedades (contenido).

El concepto de encapsulación puede considerarse en un sentido más amplio, mucho más allá del alcance de la programación orientada a objetos en su conjunto. Si hablamos de encapsulación en el nivel más alto posible de abstracción, entonces se puede considerar la encapsulación como la capacidad de un objeto para contener un determinado conjunto de otros objetos. Entonces, en relación a un programa de computadora, podemos decir que encapsula varios módulos, cada uno de los cuales a su vez encapsula algunos objetos que encapsulan métodos y propiedades, que, por cierto, también pueden ser objetos, etc.

Con base en todo lo anterior, otra representación de la encapsulación puede considerarse cualquier estructura de árbol en la que cualquier nodo del árbol encapsule a todos sus hijos inmediatos, que pueden ser hojas (primitivas que no pueden encapsular nada en sí mismas) u otros nodos.

Y, sin embargo, si hablamos de programación orientada a objetos, entonces la encapsulación es la combinación de datos y métodos dentro de un objeto.

A veces, cuando se habla de encapsulación en programación orientada a objetos, el concepto de encapsulación se equipara con el concepto de “caja negra” u ocultación de datos, pero esto no es lo mismo. Sí, en algunos lenguajes de programación orientados a objetos, mediante la encapsulación, un desarrollador puede convertir su objeto en una caja negra, pero esto se implementa mediante modificadores de acceso, que no todos los lenguajes de programación orientados a objetos tienen. El concepto de encapsulación en sí es mucho más amplio. Y aún más, podemos hacer que todas las propiedades y métodos sean accesibles desde el exterior, es decir, no puede haber ninguna caja negra, pero la encapsulación seguirá presente en cualquier objeto.

En primer lugar, gracias a la encapsulación, los objetos ya no son simplemente estructuras de datos definidas por el usuario cuyo objetivo principal es simplemente combinar lógicamente varios tipos de datos separados dentro de un nuevo tipo de datos compuesto. Gracias a la encapsulación, cada objeto ahora puede contener datos que describen el estado del objeto y su comportamiento, descritos en forma de métodos. En otras palabras, un objeto en la programación orientada a objetos ha dejado de ser un tipo de datos pasivo primitivo, cuya gestión se deja completamente al entorno externo, pero ha comenzado a tener su propio comportamiento, incluso se podría decir, alguna voluntad y inteligencia, la capacidad de responder activamente a influencias externas y cambiar su estado y de acuerdo con sus propias leyes y reglas.

En segundo lugar, la encapsulación nos brinda la capacidad de controlar el acceso a los datos de un objeto.

Limitar la visibilidad también puede considerarse como una manifestación de la propia voluntad del objeto: el objeto mismo decide qué de su comportamiento o propiedades hacer accesible a todos, qué hacer accesible solo a un determinado círculo de objetos y qué hacer completamente íntimo. que no conocerá de ningún otro objeto. Por qué, sino porque sólo el objeto mismo sabe exactamente cómo trabajar con él y cómo no. Incluso podemos hablar de una nueva filosofía de programación, donde los objetos no se parecen más a objetos sobre los que se realizan determinadas acciones, sino, por así decirlo, de una nueva forma de inteligencia sintética abstracta, con la que se puede lograr el resultado deseado al interactuar.

Y repito una vez más que es gracias a la encapsulación que un objeto puede estar dotado de cierta voluntad, inteligencia y capacidad de responder a influencias externas, y no ser un almacenamiento pasivo de datos.

Herencia

La herencia es uno de los cuatro mecanismos más importantes de la programación orientada a objetos (junto con la encapsulación, el polimorfismo y la abstracción), que le permite describir una nueva clase basada en una existente (padre), mientras que las propiedades y funcionalidades de la clase padre son tomados prestados por la nueva clase.

En otras palabras, una clase descendiente implementa la especificación de una clase ya existente (clase base). Esto le permite tratar los objetos de una clase descendiente de la misma manera que los objetos de una clase base.

Tipos de herencia

La clase de la que se produjo la herencia se denomina clase base o padre. Las clases que descienden de una clase base se denominan descendientes, herederos o clases derivadas.

Algunos idiomas utilizan clases abstractas. Una clase abstracta es una clase que contiene al menos un método abstracto, se describe en el programa, tiene campos, métodos y no se puede utilizar para crear un objeto directamente.

Es decir, sólo puedes heredar de una clase abstracta. Los objetos se crean únicamente sobre la base de clases derivadas heredadas de una abstracta.

Por ejemplo, una clase abstracta puede ser la clase base “empleado universitario”, de la cual se heredan las clases “estudiante graduado”, “profesor”, etc. Ya que las clases derivadas tienen campos y funciones comunes (por ejemplo, el campo “año”. de nacimiento”), estos miembros de una clase pueden declararse en una clase base. El programa crea objetos basados ​​en las clases “estudiante graduado” y “profesor”, pero no tiene sentido crear un objeto basado en la clase “empleado universitario”.

herencia múltiple

En herencia múltiple, una clase puede tener más de un antepasado. En este caso, la clase hereda los métodos de todos los antepasados. Las ventajas de este enfoque son una mayor flexibilidad. La herencia múltiple se implementa en C++. Otros lenguajes que ofrecen esta característica incluyen Python y Eiffel. La herencia múltiple es compatible con el lenguaje UML.

La herencia múltiple es una fuente potencial de errores que pueden ocurrir debido a la presencia de nombres de métodos idénticos en los antepasados. En los lenguajes que se posicionan como sucesores de C++ (Java, C#, etc.), se decidió abandonar la herencia múltiple en favor de las interfaces.

La mayoría de los lenguajes de programación orientados a objetos modernos (C#, C++, Java, Delphi, etc.) admiten la capacidad de heredar simultáneamente de una clase ancestral e implementar métodos de varias interfaces con la misma clase. Este mecanismo le permite reemplazar en gran medida la herencia múltiple: los métodos de interfaz deben anularse explícitamente, lo que elimina errores al heredar la funcionalidad de métodos idénticos de diferentes clases ancestrales.

  1. Parte practica

Para resolver el problema, se utiliza una estructura de programa orientada a objetos. El programa está representado por dos clases y un archivo cpp principal que contiene una interfaz de usuario para facilitar el trabajo con listas.

La clase cList es una lista lineal enlazada individualmente que consta de objetos de la clase cElement.

La clase cElement tiene la siguiente estructura:

cElemento *siguiente;

~cElemento(nulo);

datos de conjunto vacíos (int);

void setref(cElemento*);

cElemento* getref();

El campo de datos de tipo int contiene el valor numérico del elemento de la lista, el campo siguiente de tipo cElement* contiene un enlace al siguiente elemento de la lista. Los métodos setdata y getdata se utilizan para acceder al campo de datos privados de una clase para obtener y establecer el valor de este campo en consecuencia. El método setref se usa para establecer un enlace desde el elemento actual al siguiente de la lista, y getref se usa para pasar al siguiente elemento.

elemento celemento vacío::setdata(int sd)

int cElemento::getdata()

devolver esto->datos;

elemento celemento vacío::setref(cElemento* rf)

cElemento* cElemento::getref()

returnthis->siguiente;

La implementación de estos métodos es extremadamente simple, como se puede ver en los códigos de programa presentados anteriormente.

Ahora veamos la estructura de la clase cList.

#incluir "cElemento.h"

cElemento *cabeza;

void Agregar(int);

Insertar vacío(int,int);

anular Eliminar(int);

anular EliminarTodo();

Esta clase contiene un enlace al elemento principal de la lista: encabezado, de tipo cElement*. El almacenamiento de este enlace es necesario para la correcta ejecución de las operaciones de agregar, eliminar datos e imprimir la lista. El caso es que al realizar cualquiera de las operaciones anteriores, los elementos de la lista se enumeran para llegar al deseado, ya que la lista no tiene acceso aleatorio a los elementos, por lo que es más racional empezar a enumerar desde el “encabezado ”de la lista. Además de un enlace al comienzo de la lista, cada objeto de esta clase tendrá un campo elcount, que contiene el número de elementos de la lista.

Continuaremos nuestra consideración de esta clase estudiando los métodos implementados en ella para trabajar con listas.

Método Agregar: agregar datos al final de la lista.

Como parámetro, este método toma un valor numérico (variable xd), que debe almacenarse en el elemento de lista agregado.

Listac vacía::Agregar(int xd)

Así se crea un nuevo elemento y se establece el valor de su campo numérico:

cElemento *temp = nuevocElemento;

temperatura->setdata(xd);

Luego se verifica el número de elementos de la lista; si la lista está vacía, entonces se crea el elemento principal; de lo contrario, se crea el componente de lista "ordinario":

si (elcuenta ==0)

temperatura->setref(NULL);

temperatura->setref(NULL);

p->setref(temp);

Notará que la construcción anterior utiliza el método setref de la clase cElement, que es necesario para establecer una referencia al siguiente elemento de la lista; de lo contrario, la lista se desvinculará, lo que puede provocar pérdida de datos y un funcionamiento incorrecto del programa.

Cuando inicia el programa por primera vez, el método descrito anteriormente se utiliza para agregar secuencialmente elementos a la lista, con los que luego puede trabajar para detener la entrada en la línea de comando, debe ingresar el comando "detener" en lugar del valor numérico de; el elemento (ver Figura 1).

Figura 1 – El proceso de agregar elementos a la lista

Después de ingresar el comando "detener", la lista se imprime y el programa entra en modo de espera de comando (consulte la Figura 2).

Figura 2 - Lista impresa

Método de impresión: imprime la lista.

Para imprimir, es importante conocer el comienzo de la lista para poder imprimir secuencialmente los valores de todos los elementos de la lista, por lo que se establece una referencia al "encabezado" de la lista en la variable temporal, después de lo cual el Se comprueba la existencia de la lista y se muestra el mensaje correspondiente, si no se confirma, si la lista no está vacía se muestra en pantalla:

Listac vacía::Imprimir()

cElemento * temp = cabeza;

si (temp == NULL) cout mientras (temp! = NULL)

temperatura = temperatura->getref();

Método del: eliminar el elemento inicial de la lista.

Para eliminar el elemento inicial, primero debe mover la referencia al siguiente componente de la lista, convirtiéndolo en el primero de esta manera, y luego eliminar el elemento requerido:

voidcList::Del()

cElemento * temp = cabeza;

cabeza = cabeza->getref();

Método RemoveAll: elimina la lista completa.

Este método se basa en lo anterior y consiste en eliminar secuencialmente los elementos iniciales de la lista hasta eliminar toda la lista.

Lista c vacía::RemoveAll()

mientras (elcount!=0)

Para ejecutar este método, debe ingresar el comando "dellist" en el menú para trabajar con una lista (ver Figura 3).

Figura 3: Ingresando un comando para borrar la lista

Y si el usuario realmente confía en sus acciones, debe aceptar la oferta del programa, tras lo cual se eliminará toda la lista (ver Figura 4).

Figura 4 - Lista vacía

Método de eliminación: elimina un elemento de lista específico.

Un método menos radical que el anterior.

Sólo se elimina un elemento de la lista, especificado como parámetro. Esto sucede de la siguiente manera: el programa primero verifica la exactitud del parámetro ingresado, si el número del elemento que se está eliminando es menor que uno o mayor que el número total de elementos de la lista, luego muestra un mensaje de error, pero si el El programa no tiene quejas sobre el parámetro ingresado, luego los enlaces necesarios de los elementos ubicados cerca se transfieren con el que se está eliminando, de modo que la lista permanece asociada, después de lo cual se elimina el elemento requerido.

void cList::Remove(int del)

cElemento *cur = cabeza, *de;

cabeza = cabeza->getref();

si ((del>=1) && (del

mientras (j!=del-1)

cur = cur->getref();

de=cur->getref();

cur->setref(de->getref());

coutsystem("pausa");

Para ejecutar este método, debe ingresar el comando "eliminar" en el menú para trabajar con la lista. Luego ingrese el número del elemento a eliminar o el comando “atrás” para cancelar la eliminación (ver Figura 5).

Figura 5: proceso de eliminación de un elemento de la lista

La lista después de eliminar el cuarto elemento se verá así (ver Figura 6).

Figura 6 – Lista después de eliminar un elemento

Este método toma como parámetros: la posición del elemento a agregar y su valor numérico. El nuevo elemento se colocará exactamente en el lugar especificado, por lo tanto, los elementos ubicados a la derecha del actual se desplazarán una posición. Al agregar un nuevo elemento al comienzo de la lista, simplemente necesita mover el enlace de este elemento al siguiente, vinculando así la lista y especificando un enlace al elemento inicial. Una situación ligeramente diferente surge al agregar un nuevo elemento entre dos existentes. Para hacer esto, use un bucle para llegar al lugar donde se inserta el elemento, luego asocie los componentes ubicados a la derecha e izquierda del mismo con el nuevo elemento. Después de todo, qué se debe hacer, por ejemplo, si es necesario alargar la cadena: es necesario abrirla, luego unir un nuevo eslabón a la primera parte de la cadena, unir un segundo al mismo eslabón, algo similar se implementa en este método. Vale la pena señalar que si especifica una posición incorrecta para agregar, que es menor que uno o más que el número total de elementos, el programa mostrará el mensaje de error correspondiente.

void cList::Insertar (int pos, int val)

cElemento *cur = cabeza;

cElement *temp = nuevo cElement;

temperatura->setdata(val);

si ((pos>=1) && (pos

temperatura->setref(cabeza);

mientras (j!=pos-1)

mientras (j!=del-1)

p=cur->getref();

cur->setref(temp);

temperatura->setref(p);

cur->setref(de->getref());

Para ejecutar este método, debe ingresar el comando "insertar" en el menú para trabajar con la lista. Luego ingrese la posición y el valor numérico del elemento que se agregará, o el comando "atrás" para cancelar la eliminación (ver Figura 7).

Figura 7 - Proceso de inserción de un elemento

La lista después de agregar un elemento con el valor 111 a la tercera posición, la lista se verá así (ver Figura 8).

Figura 8 – Lista después de agregar un elemento

Durante la descripción, el menú para trabajar con la lista se mencionó más de una vez; cabe señalar que este menú facilita enormemente el trabajo con la lista; El algoritmo de su funcionamiento consiste en llamar cíclicamente a los mismos métodos, imprimiendo una lista, por ejemplo, hasta que se introduce un determinado comando. Se puede ver una lista de comandos disponibles ingresando "ayuda" en la consola (ver Figura 9)

Figura 9 - Comandos disponibles

El código de menú completo se presenta en el Apéndice A.

  1. Pruebas

A menudo, durante el trabajo surgen situaciones relacionadas con la entrada de datos incorrecta, lo que puede provocar que el programa falle. Por supuesto, todo programa debe implementar algoritmos de protección contra usuarios inexpertos, evitando que el programa cuelgue.

Consideremos cómo funcionan dichos algoritmos en el programa creado.

La entrada inicial de la lista se implementa mediante el siguiente código:

si (atoi(ss)!=NULL)

milista.Add(atoi(ss));

Antes de llamar al método add para agregar un nuevo elemento a la lista, se verifica la cadena ingresada. La función atoi convierte un valor de cadena en un valor numérico y devuelve NULL si la cadena de entrada no es un número. Por lo tanto, al ingresar, se ignorarán todas las líneas que no sean números, excepto la línea con el comando para detener la entrada (consulte la Figura 10).

Figura 10 – Ingresando datos incorrectos

Después de ingresar dichos datos, la lista tendrá este aspecto (consulte la Figura 11).

Figura 11 – Lista recibida

El programa sigue funcionando correctamente incluso después de introducir datos erróneos.

Se utilizan métodos similares para tratar datos incorrectos para otras operaciones de entrada presentes en el programa.

Conclusión

En este trabajo se obtuvieron conceptos sobre tipos de datos abstractos, sobre los principios de su representación en los lenguajes de programación modernos, en particular en C++. En la mayoría de los lenguajes imperativos modernos, el concepto principal utilizado para describir abstracciones en el código de un programa es el enfoque orientado a objetos. La programación orientada a objetos (POO), al igual que el enfoque de programación ADT, es, hasta cierto punto, un desarrollo de ideas sobre programación modular.

Los módulos son componentes de programa que tienen dos propiedades importantes:

En este trabajo, las listas lineales enlazadas individualmente, que son un tipo de datos abstracto, están representadas por módulos desarrollados, para acceder a cuyos estados también se implementan operaciones especiales, llamadas métodos en programación orientada a objetos.

Referencias

1. Ian Graham Métodos orientados a objetos. Principios y práctica = Métodos orientados a objetos: principios y práctica. - 3ª edición. - M.: “Williams”, 2004. - Pág. 880.

2. Anthony Sintes Sams Aprenda usted mismo la programación orientada a objetos en 21 días. - M.: “Williams”, 2002. - P. 672.

3. Bertrand Meyer Diseño de sistemas software orientado a objetos + CD. Universidad de Tecnologías de la Información de Internet - INTUIT.ru, edición rusa, 2005

4. Billig V.A. Conceptos básicos de programación en C#. Universidad de Tecnologías de la Información de Internet - INTUIT.ru, 2006

5. “Nuevos lenguajes de programación y tendencias en su desarrollo”, Ushkova V., 2005.

6. Bjarne Stroustrup “El lenguaje de programación C++” Edición especial o tercera edición ed. Binom, dialecto Nevsky, ISBN 5-7989-0226-2, 5-7940-0064-3, 0-201-70073-5

7. Bjarne Stroustrup "Diseño y evolución del lenguaje C++". DMK-Press, San Petersburgo, ISBN 5-469-01217-4, 0-201-54330-3

8. Bjarne Stroustrup "Principios de programación y práctica del uso de C++". "I.D. Williams", 2011, ISBN 978-5-8459-1621-1 (ruso)

9. Gradi Buch et al. “Análisis y diseño orientado a objetos con ejemplos de aplicación” 2ª o 3ª edición. Binom, dialecto Nevsky, Williams ISBN 978-5-8459-1401-9, 0-201-89551-X, 0-8053-5340-2, 5-7989-0067-3, 5-7940-0017-1

10. Scott Meyers "Uso eficaz de C++. 50 recomendaciones para mejorar sus programas y proyectos" DMK, Peter, ISBN 0-201-92488-9, 5-93700-006-4, 5-469-01213-1

Apéndice A

Código de menú

#incluir "cList.h"

#incluir "cadena.h"

usando el espacio de nombres estándar;

mientras (strstr(ss,"stop")==NULL)

La entrada inicial de la lista se implementa mediante el siguiente código:

si (atoi(ss)!=NULL)

sistema("cls");

mientras (strstr(com,"salir")==NULL)

coutmylist.Imprimir();

if (strstr(com,"ayuda")!=NULL) com_ind=1;

if (strstr(com,"agregar")!=NULL) com_ind=2;

if (strstr(com,"insertar")!=NULL) com_ind=3;

if (strstr(com,"eliminar")!=NULL) com_ind=4;

if (strstr(com,"dellist")!=NULL) com_ind=5;

cambiar(com_ind)

sistema("cls");

sistema("cls");

coutcoutcoutcoutcoutcoutcoutcom_ind=0;

si (strstr(ss,"atrás")==NULL)

La entrada inicial de la lista se implementa mediante el siguiente código:

si (atoi(ss)!=NULL)

sistema("cls");

//insertar elementos

si (strstr(ss,"atrás")==NULL)

La entrada inicial de la lista se implementa mediante el siguiente código:

sistema("cls");

si (strstr(ss,"atrás")==NULL)

La entrada inicial de la lista se implementa mediante el siguiente código:

milista.Insert(pos,atoi(ss));

sistema("cls");

//eliminar elementos

si (strstr(ss,"back")==NULL) está definido por un conjunto de valores dado y un conjunto de operaciones... estructuras conectadas datosliza. Estructura datos es una colección de elementos datos, entre los cuales... en la memoria de la computadora se llama abstracto o lógico. Más a menudo...

  • Múltiple tipo datos. Conjuntos

    Conferencia >> Informática, programación.

    ... tipo similares a los simples tipos datos. Múltiple tipos se describen en la sección tipos... El RT se puede describir. Abstracto estructuras computacionales que describen la entrada... otros casos tipos todos los componentes lista debe coincidir tipo componentes del archivo. ...

  • Bases de datos orientadas a objetos datos operando en redes distribuidas

    Resumen >> Ciencias de la Computación

    Desarrollar áreas de lenguajes de programación con abstracto tipos datos y lenguajes de programación orientados a objetos. ... tipos datos- lista y matriz. Cada literal se identifica de forma única mediante un índice en la matriz y un número de serie en lista ...

  • Abstracto modelos de seguridad de la información

    Resumen >> Ciencias de la Computación

    Protección de la información………………………………………………………………..17 Abstracto Modelos de seguridad de la información... que rigen la interacción con ambos. tipos datos(Reglas de Certificación): Todo... varias variaciones y adiciones al existente lista. Niveles de seguridad: ciertos...

  • ¡Buenos días, residentes de Khabra!

    La siguiente publicación es un resumen de mis pensamientos sobre la naturaleza de las clases y ADT. Estos pensamientos se complementan con citas interesantes de libros de gurús del desarrollo de software.

    Apéndice A 27

    Empecemos acercándonos poco a poco a la definición de ADT. Un ADT es ante todo un tipo de datos, lo que significa lo siguiente:
    la presencia de determinadas operaciones disponibles sobre elementos de este tipo;
    así como los datos contra los cuales se realizan estas operaciones (rango de valores).

    ¿Qué significa la palabra "abstracto"? En primer lugar, el concepto de “abstracción” significa centrar la atención en algo importante y, al mismo tiempo, debemos distraernos de detalles que no son importantes en este momento. La definición de abstracción está bien tratada en el libro de Grady Booch. La definición es la siguiente:

    La abstracción es la selección y la impartición a un conjunto de objetos de propiedades comunes que determinan sus límites conceptuales y los distinguen de todos los demás tipos de objetos.
    En otras palabras, la abstracción nos permite “arrojar luz” sobre los datos del objeto que necesitamos y, al mismo tiempo, “sombrear” los datos que no son importantes para nosotros.

    Entonces, ¿qué sucede si fusionamos los conceptos de “tipo de datos” y “abstracción”? Recibiremos un tipo de datos que nos proporciona un determinado conjunto de operaciones que aseguran el comportamiento de los objetos de este tipo de datos, y este tipo de datos también ocultará los datos con los que se implementa este comportamiento. De ahí llegamos al concepto de TDA:

    Un ADT es un tipo de datos que oculta su implementación interna a los clientes.
    Lo sorprendente es que al aplicar la abstracción, ADT nos permite no preocuparnos por los detalles de implementación de bajo nivel, sino trabajar con la esencia de alto nivel del mundo real (Steve McConnell).

    Creo que al desarrollar un ADT, primero es necesario definir una interfaz, ya que la interfaz no debe depender de la representación interna de los datos en el ADT. Después de definir las operaciones que componen la interfaz, debe centrarse en los datos que implementarán el comportamiento especificado del ADT. Como resultado, obtendremos una determinada estructura de datos, un mecanismo que nos permite almacenar y procesar datos. Al mismo tiempo, la belleza de ADT es que si queremos cambiar la representación interna de los datos, no tenemos que recorrer todo el programa y cambiar cada línea de código que depende de los datos que queremos cambiar. Un ADT encapsula estos datos, lo que le permite cambiar el funcionamiento de objetos de este tipo, en lugar de todo el programa.

    Ventajas del ATD

    Usar un ADT tiene muchas ventajas (todas las ventajas descritas se pueden encontrar en el libro "Perfect Code" de Steve McConnell):

    • Encapsulación de detalles de implementación.
      Esto significa que una vez que hemos encapsulado los detalles de implementación del ADT, proporcionamos al cliente una interfaz con la que puede interactuar con el ADT. Al cambiar los detalles de implementación, la percepción de los clientes sobre la operación de ADT no cambiará.
    • Complejidad reducida.
      Al abstraernos de los detalles de implementación, nos centramos en la interfaz, es decir, en lo que el ADT puede hacer, en lugar de en cómo se hace. Además, ADT nos permite trabajar con la esencia del mundo real.
    • Limitar el alcance del uso de datos.
      Usando un ADT, podemos estar seguros de que los datos que representan la estructura interna del ADT no dependerán de otras partes del código. En este caso, se materializa la “independencia” de la ADT.
    • Interfaz altamente informativa.
      ADT le permite presentar toda la interfaz en términos de entidades de dominio, lo que, como ve, aumenta la legibilidad y el contenido informativo de la interfaz.

    Steve McConnell recomienda representar tipos de datos de bajo nivel, como una pila o una lista, como un ADT. Pregúntese qué representa esta lista. Si representa una lista de empleados del banco, entonces considere el ATD como una lista de empleados del banco.

    Entonces, descubrimos qué es ADT y mencionamos las ventajas de su uso. Ahora vale la pena señalar que al desarrollar clases en programación orientada a objetos, uno debe pensar, en primer lugar, en ADT. Al mismo tiempo, como dijo Steve McConnell, no se programa en un idioma, sino con la ayuda de un idioma. Es decir, programará más allá de los límites del lenguaje, sin limitarse a pensar en términos de matrices o tipos de datos simples. En cambio, pensará en un alto nivel de abstracción (por ejemplo, en términos de hojas de cálculo o listas de empleados). Una clase no es más que una adición y una forma de implementar el concepto ADT. Incluso podemos representar la clase como una fórmula:
    Clase = ADT + Herencia + Polimorfismo.
    Entonces, ¿por qué debería pensar en ADT al desarrollar clases? Porque, primero, debemos decidir qué operaciones conformarán la interfaz de la clase futura, qué datos ocultar y a cuáles proporcionar acceso público. Necesitamos pensar en hacer que la interfaz sea altamente informativa, hacer que el código sea fácil de optimizar y probar, y cómo podemos proporcionar la abstracción correcta para que podamos pensar en entidades del mundo real en lugar de detalles de implementación de bajo nivel. Creo que es después de definir la ADT que deberíamos pensar en cuestiones de herencia y polimorfismo.

    Vale la pena señalar que el concepto ADT ha encontrado una amplia aplicación en la programación orientada a objetos, ya que es este concepto el que complementa la programación orientada a objetos y permite reducir la complejidad de los programas en el mundo rápidamente cambiante de los requisitos de software.

    Escribí este artículo para llamar la atención de los desarrolladores sobre ADT para mejorar la calidad del trabajo y el desarrollo de software.

    Fuentes utilizadas:

    Steve McConnell - "Código perfecto";
    Robert Sedgwick - "Algoritmos en Java".

    El desarrollo de modelos abstractos para datos y formas de procesarlos es un componente crítico de la resolución de problemas informáticos. Vemos ejemplos de esto tanto en un nivel bajo en la programación cotidiana (por ejemplo, cuando se usan matrices y listas enlazadas, como se analiza en) como en un nivel alto cuando se resuelven problemas aplicados (como cuando se resuelve el problema de conectividad usando un bosque de búsqueda conjunta). en "Introducción"). Esta conferencia analiza los tipos de datos abstractos (en adelante, ADT), que le permiten crear programas utilizando abstracciones de alto nivel. Los tipos de datos abstractos permiten separar las transformaciones abstractas (conceptuales) que los programas realizan en los datos de cualquier representación concreta de la estructura de datos y de cualquier implementación concreta del algoritmo.

    Todos los sistemas informáticos se basan en niveles de abstracción: determinadas propiedades físicas del silicio y de otros materiales permiten la adopción de un modelo abstracto de un bit, que puede adoptar los valores binarios 0-1; luego se construye un modelo abstracto de la máquina sobre las propiedades dinámicas de los valores de un determinado conjunto de bits; además, basándose en el principio de funcionamiento de una máquina bajo el control de un programa en lenguaje de máquina, se construye un modelo abstracto de un lenguaje de programación; y finalmente, se construye un concepto abstracto de algoritmo, implementado como un programa en C++. Los tipos de datos abstractos permiten continuar este proceso y desarrollar mecanismos abstractos para problemas computacionales específicos a un nivel superior al proporcionado por el sistema C++, desarrollar mecanismos abstractos que están orientados a aplicaciones específicas y son adecuados para resolver problemas en numerosos dominios de aplicaciones. y también crear mecanismos abstractos de nivel superior que utilicen estos diseños básicos. Los tipos de datos abstractos nos proporcionan un conjunto de herramientas infinitamente ampliable para resolver cada vez más problemas nuevos.

    Por un lado, el uso de construcciones abstractas le libera de preocupaciones sobre su implementación detallada; por otra parte, cuando actuación El programa es importante, necesita conocer los costos de realizar operaciones básicas. Usamos muchas abstracciones básicas integradas en hardware ordenador y que sirve de base para instrucciones de máquinas; implementar otras abstracciones en software; y utilizar abstracciones adicionales proporcionadas por software de sistema previamente escrito. Las construcciones abstractas de alto nivel a menudo se derivan de construcciones más simples. El mismo principio básico se aplica en todos los niveles: encontrar las operaciones más importantes en los programas y las características más importantes de los datos, y luego definir ambas con precisión en el nivel abstracto y desarrollar mecanismos concretos eficientes para implementarlas. En esta conferencia veremos muchos ejemplos de la aplicación de este principio.

    Desarrollar un nuevo nivel de abstracción requerirá (1) definir los objetos abstractos que deben manipularse y las operaciones que deben realizarse sobre ellos; (2) representar los datos en alguna estructura de datos e implementar las operaciones; (3) y (lo más importante) garantizar que estos objetos sean convenientes de usar para resolver problemas aplicados. Estos puntos también se aplican a tipos de datos simples, por lo que los mecanismos básicos para soportar tipos de datos que se analizaron en "Estructuras de datos elementales" se pueden adaptar para nuestros propósitos. Sin embargo, C++ ofrece una extensión importante al mecanismo estructural llamado clase. Las clases son extremadamente útiles para crear capas de abstracción y, por lo tanto, se consideran la herramienta principal utilizada para este propósito en el resto del libro.

    Definición 4.1. Un tipo de datos abstracto (ADT) es un tipo de datos (un conjunto de valores y un conjunto de operaciones sobre esos valores) al que solo se puede acceder a través de una interfaz. Un programa que utiliza un ADT se llamará cliente y un programa que contenga una especificación de este tipo de datos se llamará implementación.

    Es la palabra que sólo hace que el tipo de datos sea abstracto: en el caso de un ADT, los programas cliente no tienen acceso a los valores de datos de ninguna otra manera que no sean las operaciones descritas en la interfaz. La representación de estos datos y las funciones que implementan estas operaciones están en la implementación y están completamente separadas por la interfaz del cliente. Decimos que una interfaz es opaca: el cliente no puede ver la implementación a través de la interfaz.

    En los programas C++ esta distinción suele hacerse un poco más clara, ya que es más fácil crear una interfaz incluyendo presentación de datos, pero especificando que los programas cliente no pueden acceder directamente a los datos. En otras palabras, los desarrolladores de programas cliente pueden saber presentación de datos, pero no puede usarlo de ninguna manera.

    Como ejemplo, considere la interfaz de tipo de datos para puntos (programa 3.3) de la sección 3.1 “Estructuras de datos elementales”. Esta interfaz declara explícitamente que los puntos se representan como estructuras que consisten en un par de números de punto flotante, denominados xey. Este tipo de uso de tipos de datos es común en grandes sistemas de software: desarrollamos un conjunto de convenciones para representar datos (y también definimos un conjunto de operaciones asociadas con ellos) y hacemos que estas reglas estén disponibles a través de una interfaz para que puedan ser utilizadas por programas cliente que forman parte del gran sistema. El tipo de datos garantiza que todas las partes del sistema sean coherentes al representar las estructuras de datos subyacentes de todo el sistema. No importa lo buena que sea esta estrategia, tiene un defecto: si necesitas cambiar presentación de datos, entonces deberá cambiar todos los programas cliente. El programa 3.3 nuevamente nos da un ejemplo simple: una de las razones para diseñar este tipo de datos es facilitar que los programas de los clientes trabajen con puntos, y esperamos que los clientes tengan acceso a las coordenadas de los puntos individuales cuando sea necesario. Pero no podemos pasar a una representación de datos diferente (por ejemplo, coordenadas polares o coordenadas 3D, o incluso diferentes tipos de datos para coordenadas individuales) sin cambiar todos los programas cliente.

    Por el contrario, el Programa 4.1 contiene una implementación de un tipo de datos abstracto correspondiente al tipo de datos del Programa 3.3, pero utilizando una clase de lenguaje C++ que define inmediatamente tanto los datos como sus operaciones asociadas. El programa 4.2 es un programa cliente que trabaja con este tipo de datos. Estos dos programas realizan los mismos cálculos que los programas 3.3 y 3.8. Ilustran una serie de propiedades básicas de las clases que veremos ahora.

    Cuando escribimos una definición como int i en un programa, le estamos diciendo al sistema que reserve un área de memoria para datos del tipo int (integrado), a los que se puede acceder con el nombre i. En el lenguaje C++, existe un término para entidades como objeto. Cuando un programa escribe una definición como PUNTO p, se dice que crea un objeto de clase PUNTO al que se puede hacer referencia con el nombre p. En nuestro ejemplo, cada objeto contiene dos elementos de datos, denominados x e y. Al igual que con las estructuras, se les puede hacer referencia con nombres como p.y.

    Los miembros de datos xey se denominan miembros de datos de la clase. La clase también puede definir funciones miembro que implementen operaciones asociadas con este tipo de datos. Por ejemplo, la clase definida en el Programa 4.1 tiene dos funciones miembro denominadas PUNTO y distancia.

    Los programas cliente, como el Programa 4.2, pueden llamar a las funciones miembro asociadas con un objeto especificando sus nombres de la misma manera que los nombres de los datos contenidos en una estructura. Por ejemplo, la expresión p.distance(q) calcula la distancia entre los puntos p y q (se debe devolver la misma distancia llamando a q.distance(p) ). La función PUNTO(), la primera función del Programa 4.1, es una función miembro especial llamada constructor: tiene el mismo nombre que una clase y se llama cuando se desea crear un objeto de esa clase.

    Programa 4.1. Implementación de la clase PUNTO

    Esta clase define un tipo de datos que consta de un conjunto de valores que son "pares de números de punto flotante" (que se supone interpretados como puntos en el plano cartesiano), así como dos funciones miembro definidas para todas las instancias del Clase PUNTO: la función PUNTO() , que es un constructor que inicializa coordenadas con valores aleatorios entre 0 y 1, y una función distancia(PUNTO) , que calcula la distancia a otro punto. presentación de datos es privado y solo las funciones miembro pueden acceder a él o modificarlo. Las funciones de los miembros en sí son públicas y accesibles para cualquier cliente. El código se puede guardar, por ejemplo, en un archivo llamado POINT.cxx.

    #incluir clase PUNTO (privado: float x, y; público: PUNTO() ( x = 1.0*rand()/RAND_MAX; y = 1.0*rand()/RAND_MAX; ) distancia flotante(PUNTO a) ( float dx = x-a.x , dy = y-a.y; return sqrt(dx*dx + dy*dy);

    Programa 4.2. Programa cliente para la clase PUNTO (encontrar el punto más cercano)

    Esta versión del programa 3.8 es un cliente que utiliza el PUNTO ADT definido en el programa 4.3. La nueva operación crea una matriz de objetos PUNTO (llamando al constructor POINT() para inicializar cada objeto con valores de coordenadas aleatorios). La expresión a[i].distance(a[j]) llama a la función miembro de distancia en el objeto a[i] con el argumento a[j] .

    #incluir #incluir #include "PUNTO.cxx" int main(int argc, char *argv) ( float d = atof(argv); int i, cnt = 0, N = atoi(argv); PUNTO *a = nuevo PUNTO[N]; para (yo = 0; yo< N; i++) for (int j = i+1; j < N; j++) if (a[i].distance(a[j]) < d) cnt+ + ; cout << cnt << " пар в радиусе " << d << endl; }

    La definición de PUNTO p en el programa cliente asigna una región de memoria para el nuevo objeto y luego (usando la función PUNTO()) asigna a cada uno de sus dos elementos de datos un valor aleatorio en el rango de 0 a 1.

    Este estilo de programación, a veces llamado programación orientada a objetos, es totalmente compatible con la construcción de clase C++. Una clase puede considerarse una extensión del concepto de estructura, donde no solo se combinan datos, sino que también se definen operaciones sobre estos datos. Puede haber muchos objetos diferentes que pertenezcan a la misma clase, pero todos son similares en que sus miembros de datos pueden tomar el mismo conjunto de valores y se puede realizar el mismo conjunto de operaciones en esos miembros de datos; en general, estos son instancias del mismo tipo de datos. En la programación orientada a objetos, los objetos están diseñados para procesar los datos de sus miembros (en lugar de utilizar funciones independientes para procesar los datos almacenados en los objetos).

    Estamos viendo el ejemplo de clase pequeña descrito anteriormente sólo para familiarizarnos con las características básicas de las clases; por lo que está lejos de estar completo. En código real, tendremos muchas más operaciones para la clase de puntos. Por ejemplo, en el programa 4.1 ni siquiera hay operaciones que permitan conocer los valores de las coordenadas xey. Como veremos, agregar estas y otras operaciones es una tarea bastante sencilla. En la Parte 5 veremos más de cerca las clases para el punto y otras abstracciones geométricas como líneas y polígonos.

    En C++ (pero no en C), las estructuras también pueden tener funciones asociadas. La diferencia clave entre clases y estructuras se relaciona con el acceso a la información, que se caracteriza por palabras clave.

    Todos los tipos de datos integrados son abstractos, aunque rara vez se les llama así.

    Concepto de abstracción

    Una abstracción es un juicio o idea sobre algún objeto que contiene sólo propiedades que son esenciales en un contexto determinado. La abstracción le permite combinar instancias de objetos en grupos, dentro de los cuales no es necesario considerar las propiedades generales de los objetos, es decir, abstraerse de ellos. La abstracción es un antídoto eficaz contra la complejidad de la programación, ya que permite al programador centrarse en las propiedades esenciales de los objetos. Tipos de abstracciones: abstracción del proceso Y abstracción de datos.

    Abstracción de procesos. Todas las rutinas son abstracciones de procesos; definen la forma en que un programa determina que algún proceso debe realizarse, sin especificar los detalles de cómo debe realizarse. La capacidad de abstraerse de los muchos detalles del algoritmo que ejecuta una subrutina hace posible crear, leer y comprender programas grandes. Cualquier abstracción de datos son operaciones definidas como abstracciones de procesos.

    Abstracción de datos. Un tipo de datos abstracto es una encapsulación que contiene sólo representaciones de un tipo de datos específico y rutinas que realizan operaciones en ese tipo de datos. Al utilizar el control de acceso, se pueden ocultar detalles sin importancia de una descripción de tipo a los módulos externos que utilizan ese tipo. Los módulos de programa que utilizan un tipo de datos abstracto pueden declarar variables de ese tipo, aunque la representación real del tipo esté oculta para ellos. Una instancia de un tipo de datos abstracto se denomina objeto.

    La razón para crear abstracción de tipos de datos y abstracción de procesos es como un remedio anti-complejidad, una forma de hacer que los programas grandes y/o complejos sean más manejables.

    Supongamos que nuestro objeto es un círculo. Entonces el mensaje enviado a este objeto podría ser: "dibújate a ti mismo". Cuando decimos que se envía un mensaje a un objeto, en realidad estamos llamando a alguna función de este objeto (componente de función). Entonces, en el ejemplo anterior, llamaremos a una función que dibujará un círculo en la pantalla.

    Dividir un programa en contenedores sintácticos que contienen grupos de rutinas y datos relacionados lógicamente. Estos contenedores sintácticos se denominan módulos y el proceso de desarrollo de ellos se denomina modularización.

    Compilación de un programa a partir de colecciones de subrutinas y datos, cada uno de los cuales se puede compilar por separado sin volver a compilar el resto del programa. Este conjunto se llama unidad de compilación.

    La encapsulación es una forma de combinar subrutinas y los datos que procesan en un solo todo. La encapsulación, que se compila por separado o de forma independiente, es la base del sistema abstracto y la organización lógica del conjunto de cálculos correspondientes.

    Tipos de datos abstractos definidos por el usuario

    Los tipos de datos abstractos definidos por el usuario deben tener las siguientes propiedades:

    1) una definición de tipo, que permite a los módulos de programa declarar variables de este tipo, mientras crean una representación real de estas variables en la memoria.

    2) un conjunto de operaciones para manipular objetos de un tipo determinado.

    Definición formal de un tipo de datos abstracto en el contexto de tipos definidos por el usuario: Un tipo de datos abstracto es un tipo de datos que satisface las dos condiciones siguientes.

      La representación (definición de tipo) y las operaciones sobre objetos de un tipo determinado están contenidas en una unidad sintáctica; las variables de un tipo determinado se pueden crear en otros módulos.

      La representación de objetos de un tipo determinado está oculta para los módulos de programa que utilizan este tipo y se pueden realizar operaciones en objetos que están directamente previstos en la definición del tipo.

    Empaquetar la representación de tipos y las operaciones en una unidad sintáctica separada permite organizar el programa en unidades lógicas que se pueden compilar por separado. En segundo lugar, es posible modificar la representación de objetos de un tipo determinado o las operaciones con ellos en una parte separada del programa. Ocultar los detalles de representación de tipos tiene ventajas. Los clientes no pueden "ver" los detalles de la representación de un objeto y su código no depende de esa representación. De esta manera, las representaciones de objetos se pueden cambiar en cualquier momento sin necesidad de cambios en el código de los clientes. Otra ventaja obvia e importante de ocultar información es una mayor confiabilidad. Los clientes no pueden cambiar directamente las representaciones subyacentes de los objetos, ya sea intencionalmente o accidentalmente, y por lo tanto aumenta la integridad de dichos objetos. Los objetos sólo pueden modificarse mediante las operaciones previstas para este fin.

    Problemas de desarrollo de tipos

    Debería ser posible hacer que el nombre del tipo y los encabezados de subrutina sean visibles para los clientes de la abstracción. Esto permite a los clientes declarar variables de tipo abstracto y manipular sus valores. Aunque el nombre del tipo debe ser visible externamente, su definición debe estar oculta.

    Hay muy pocas operaciones integradas comunes que se pueden realizar en objetos de tipos abstractos, a diferencia de las operaciones proporcionadas por la definición de tipo. Estas operaciones incluyen asignaciones y pruebas de igualdad y desigualdad. Si el idioma no permite a los usuarios sobrecargar el operador de asignación, entonces debería estar en línea. Las pruebas de igualdad y desigualdad deben estar predefinidas en algunos casos, pero no en otros. El diseñador de tipos debe definir él mismo las operaciones para la mayoría de los tipos de datos abstractos.

    Smalltalk, C++ y Java admiten directamente tipos de datos abstractos.

    Tipos de datos abstractos en C++

    Los lenguajes Ada y Modula-2 proporcionan encapsulación que se puede utilizar para modelar tipos de datos abstractos, y C++ introduce el concepto de clases que admiten directamente tipos de datos abstractos. En C++, las clases son tipos, pero los paquetes Ada y los módulos Modula-2 no son tipos. Los paquetes y módulos se importan, lo que permite a la unidad del programa importador declarar variables de cualquier tipo definido en el paquete o módulo. En un programa C++, las variables se declaran como entidades que tienen el tipo de una clase determinada. De esta manera, las clases se parecen mucho más a tipos integrados que a paquetes o módulos. Una unidad de software que ve un paquete en Ada o un módulo en Modula-2 tiene acceso a cualquier entidad pública simplemente por su nombre. Una unidad de programa C++ que declara una instancia de una clase también tiene acceso a cualquier entidad pública de esa clase, pero sólo a través de una instancia de esa clase.



    
    Arriba