Está en la página 1de 52

POE-0606

PROGRAMACIÓN AVANZADA I
UV
-
I PARCIAL
PROGRAMACION AVANZADA I
-

I PARCIAL
-

- -
Objetivo General de la asignatura:

✔Conocer los principios metodológicos de la


programación orientada a objetos, procesamiento
de flujos de E/S, multiprocesamiento, diseño de
interfaces gráficas y el manejo de la teoría de
excepciones.
OBJETIVOS ESPECÍFICOS

Conceptualizar la terminología usada en la programación orientada a objetos y


sus diversos componentes.

Desarrollar programas computacionales basados en estándares, normas y


principios de diseño y reutilización que permitan ofrecer soluciones eficaces.

Establecer criterios de selección de un lenguaje de programación que


garanticen el desarrollo adecuado de un proyecto informático.
COMPETENCIAS A ALCANZAR

Conceptualiza la terminología usada en la programación orientada a objetos y sus diversos componentes.

Desarrolla programas computacionales basados en estándares, normas y principios de diseño


reutilización para ofrecer soluciones eficaces.

Establece criterios de selección de un lenguaje de programación que garantice el desarrollo adecuado de


un proyecto informático.
INTRODUCCIÓN

La Programación Orientada a Objetos (POO) es un Paradigma de programación, es decir, un


modelo o un estilo de programación que nos da unas guías sobre cómo trabajar con él. Se
basa en el concepto de clases y objetos. Este tipo de programación se utiliza para
estructurar un programa de software en piezas simples y reutilizables de planos de código
(clases) para crear instancias individuales de objetos.
Con el paradigma de Programación Orientado a Objetos lo que buscamos es dejar de
centrarnos en la lógica pura de los programas, para empezar a pensar en objetos, lo que
constituye la base de este paradigma. Esto nos ayuda muchísimo en sistemas grandes, ya
que en vez de pensar en funciones, pensamos en las relaciones o interacciones de los
diferentes componentes del sistema.
Un programador diseña un programa de software organizando piezas de información y
comportamientos relacionados en una plantilla llamada clase. Luego, se crean objetos
individuales a partir de la plantilla de clase. Todo el programa de software se ejecuta
haciendo que varios objetos interactúen entre sí para crear un programa más grande.
CONTENIDO DEL PRIMER PARCIAL

2. Polimorfismo 3. Procedimiento de
• 2.1. Relación de Flujos E/S
objetos en una • 3.1. Entrada de Flujos
jerarquía • 3.2. Salida de Flujos
1. Programación
Orientada a Objetos • 3.3.Procesamiento de
archivos
1. PROGRAMACIÓN ORIENTADA
-

A OBJETOS
-

- -
1.1 PRINCIPIOS DE LA PROGRAMACIÓN ORIENTADA A OBJETOS

La encapsulación contiene toda la información importante de un objeto dentro del mismo y solo expone la
información seleccionada al mundo exterior.
Esta propiedad permite asegurar que la información de un objeto esté oculta para el mundo exterior,
agrupando en una Clase las características o atributos que cuentan con un acceso privado, y los
comportamientos o métodos que presentan un acceso público.

La abstracción es cuando el usuario interactúa solo con los atributos y métodos seleccionados de un
objeto, utilizando herramientas simplificadas de alto nivel para acceder a un objeto complejo.
1.1 PRINCIPIOS DE LA PROGRAMACIÓN ORIENTADA A OBJETOS

La herencia define relaciones jerárquicas entre clases, de forma que atributos y métodos comunes puedan ser
reutilizados. Las clases principales extienden atributos y comportamientos a las clases secundarias. A través de la
definición en una clase de los atributos y comportamientos básicos, se pueden crear clases secundarias, ampliando así
la funcionalidad de la clase principal y agregando atributos y comportamientos adicionales.

El polimorfismo consiste en diseñar objetos para compartir comportamientos, lo que nos permite procesar objetos de
diferentes maneras. Es la capacidad de presentar la misma interfaz para diferentes formas subyacentes o tipos de
datos. Al utilizar la herencia, los objetos pueden anular los comportamientos principales compartidos, con
comportamientos secundarios específicos.
1.1 PRINCIPIOS DE LA PROGRAMACIÓN ORIENTADA A OBJETOS

La programación orientada a objetos se basa en el concepto de crear un modelo del problema de destino en sus
programas. La programación orientada a objetos disminuye los errores y promociona la reutilización del código. Python
es un lenguaje orientado a objetos. Los objetos definidos en Python tienen las características siguientes:

Identidad Estado Comportamiento

• Cada objeto debe ser distinguido y • Cada objeto debe ser capaz de • Cada objeto debe ser capaz de
ello debe poder demostrarse almacenar el estado. Para este fin, manipular su estado. Para este fin
mediante pruebas. Las existen atributos, tales como existen métodos.
pruebas e existen para este fin. variables de instancias y campos.
1.1 PRINCIPIOS DE LA PROGRAMACIÓN ORIENTADA A OBJETOS

Python incluye las características siguientes para dar soporte a la programación orientada a objetos:

Encapsulación con ocultación de


Herencia con polimorfismo. Python da datos. Python permite ocultar los
Creación de objetos basada en
soporte a la herencia individual y atributos. Cuando se ocultan los
clases. Las clases son plantillas para la
múltiple. Todos los métodos de instancias atributos, se puede acceder a los mismos
creación de objetos. Los objetos son
de Python son polimórficos y se pueden desde fuera de la clase únicamente
estructuras de datos con el
alterar temporalmente mediante mediante los métodos de la clase. Las
comportamiento asociado.
subclases. clases implementan métodos para
modificar los datos.
1.1 PRINCIPIOS DE LA PROGRAMACIÓN ORIENTADA A OBJETOS

Principales lenguajes

En la actualidad existen diferentes lenguajes de


programación orientada a objetos, como C++, Objetive C, Java, Ruby,
Visual Basic, Visual C Sharp, Simula, Perl, TypeScript, Smalltalk, PHP
o Python. C++ y Java son los dos lenguajes de programación
orientada a objetos más usados, por lo que, si quieres aprender este
tipo de programación para ampliar tus oportunidades en el mercado
laboral, es conveniente que pases un curso en Java o C++.
1.1 PRINCIPIOS DE LA PROGRAMACIÓN ORIENTADA A OBJETOS

Por otra parte, Python, PHP y Ruby son otros lenguajes de programación orientada
a objetos muy populares, aunque más enfocados en la programación, desarrollo
web y de aplicaciones para móviles. Por consiguiente, un curso Python Online o en
PHP también te abrirá muchas puertas.

Por supuesto, existen otros lenguajes de programación orientada a objetos de


carácter más específico, como es el caso de ADA, que tiene un enfoque en la
seguridad y está basado en un tipado muy fuerte, por lo que se usa para
desarrollar aplicaciones de defensa, gestión de tráfico aéreo y en la
industria aeroespacial.
2. POLIMOSFISMO -

- -
2. POLIMOSFISMO

El polimorfismo es la tercera característica esencial de los lenguajes de programación orientados a


objetos, después de la abstracción de datos y la herencia. Proporciona otra dimensión de separación
de la interfaz de la implementación, separa el qué del cómo. El polimorfismo permite una
organización de código y una legibilidad del mismo mejorada, además de la creación de programas
ampliables que pueden "crecer", no sólo durante la creación original del proyecto sino también
cuando se deseen añadir nuevas características.
2. POLIMOSFISMO

La encapsulación crea nuevos tipos de datos mediante la combinación de características y comportamientos. La


ocultación de la implementación separa la interfaz de la implementación haciendo los detalles privados. Este tipo
de organización mecánica tiene bastante sentido para alguien con un trasfondo procedural de programación.

Pero el polimorfismo tiene que ver con la separación en términos de tipos. En el capítulo anterior se vio como la
herencia permite el tratamiento de un objeto como si fuera de sus propio tipo o del tipo base. Esta característica
es crítica porque permite que varios tipos (derivados de un mismo tipo base) sean tratados como si fueran uno
sólo, y un único fragmento de código se puede ejecutar de igual forma en todos los tipos diferentes.
2. POLIMOSFISMO
2. POLIMOSFISMO

El método Musica.afinar( ) acepta una referencia a Instrumento, pero también cualquier cosa que se derive de
Instrumento. En el método main,( ) se puede ver que ocurre esto pues se pasa una referencia Viento a afinar,
sin que sea necesaria ninguna conversión. Esto es aceptable; la interfaz de Instrumento debe existir en Viento,
puesto que Viento se hereda de Instrumento. Hacer una conversión hacia arriba de Viento a Instrumento
puede "estrechar" esa interfaz, pero no puede reducirlo a nada menos de lo contenido en la interfaz de
Instrumento.

Esto es exactamente lo que permite hacer el polimorfismo. Sin embargo, la mayoría de programadores que
provienen de lenguajes procedurales, tienen problemas para entender el funcionamiento de esta
característica.
2. POLIMOSFISMO

EL CAMBIO

La dificultad con Musica.java se puede ver ejecutando el programa. La salida es Viento.tocar( ) Ésta es,
ciertamente, la salida deseada, pero no parece tener sentido que funcione de esa forma. Obsérvese el
método afinar( ):
2. POLIMOSFISMO

Recibe una referencia a Instrumento. Por tanto, ¿cómo puede el compilador saber que esta referencia a
Instrumento apunta a Viento en este caso, y no a Cuerda o Metal? El compilador de hecho no puede
saberlo.

La ligadura en las llamadas a métodos

La conexión de una llamada a un método se denomina ligadura. Cuando se lleva a cabo la ligadura antes
de ejecutar el programa (por parte del compilador y el montador, cuando lo hay) se denomina ligadura
temprana. Puede que este término parezca extraño pues nunca ha sido una opción con los lenguajes
procedurales. Los compiladores de C tienen un único modo de invocar a un método utilizando la ligadura
temprana.
2. POLIMOSFISMO

Toda ligadura de métodos en Java se basa en la ligadura tardía a menos que se haya declarado un método
como constante. Esto significa que ordinariamente no es necesario tomar decisiones sobre si se dará la
ligadura tardía, sino que esta decisión se tomará automáticamente.

¿Por qué declarar un método como constante? Como se comentó en el capítulo anterior, evita que nadie
superponga el método. Todavía más importante, "desactiva" ligadura dinámica, o mejor, es que, le dice al
compilador que este tipo de ligadura no es necesaria. Esto permite al compilador generar código
ligeramente más eficiente para llamadas a métodos constantes
2. POLIMOSFISMO

PRODUCIENDO EL COMPORTAMIENTO ADECUADO

Una vez que se sabe que toda la ligadura de métodos en Java se da de forma polimórfica a
través de ligadura tardía, se puede escribir código que trate la clase base y saber que todas
las clases derivadas funcionarán correctamente al hacer uso de ese mismo código. Dicho de
otra forma, se "envía un mensaje a un objeto y se deja que éste averigüe la opción correcta
a realizar".
2. POLIMOSFISMO

El ejemplo de los polígonos tiene una clase base denominada Polígono y varios tipos derivados: Círculo, Cuadrado y
Triángulo, etc. La razón por la que el ejemplo funciona tan bien es porque se puede decir sin problema "un círculo es
un tipo de polígono" y se entiende. El diagrama de herencia muestra las relaciones:
2. POLIMOSFISMO

La conversión hacia arriba podría darse en una sentencia tan simple como:

Polígono s = new Circulo();

Aquí, se crea un objeto Círculo y la referencia resultante se asigna directamente a un Polígono, lo que
podría parecer un error (asignar un tipo a otro); y sin embargo, está bien porque un Círculo es un Polígono
por herencia. Por tanto, el compilador se muestra de acuerdo con la sentencia y no muestra ningún
mensaje de error.
2. POLIMOSFISMO

Supóngase que se invoca a uno de los métodos de la clase base (que han sido superpuestos en clases
derivadas) :

s.dibujar ();

De nuevo, se podría esperar que se invoque al método dibujar( ) de Polígono porque se trata, después de
todo, de una referencia a Polígono -por tanto, ¿cómo podría el compilador saber que tiene que hacer
otra cosa? Y sin embargo, se invoca al Círculo.dibujar( ) correcto debido a la ligadura tardía
(polimorfismo) .
2. POLIMOSFISMO

La clase principal Polígonos contiene un método estático llamado poligonoAleatorio( ) que produce una
referencia a un objeto Polígonos seleccionado al azar cada vez que se le invoca. Fíjese que se realiza una
conversión hacia arriba en cada sentencia return que toma una referencia a un Círculo, Cuadrado o
Triángulo, y lo envía fuera del método con tipo de retorno Polígonos. Así, al invocar a este método no se
tendrá la opción de ver de qué tipo específico es el valor devuelto, dado que siempre se obtendrá
simplemente una referencia a Polígono
2. POLIMOSFISMO

El método main( ) contiene un array de referencias Polígono rellenadas


mediante llamadas a poligonoAleatorio( ). En este punto se sabe que se tienen
objetos de tipo Polígono, pero no se sabe nada sobre nada más específico que
eso (y tampoco el compilador). Sin embargo, cuando se recorre este array y se
invoca ,al método dibujar( ) para cada uno de sus objetos, mágicamente se da
el comportamiento correcto específico de cada tipo, como se puede ver en un
ejemplo de salida:
2. POLIMOSFISMO

Por supuesto, dado que los polígonos se eligen cada vez al azar, cada ejecución tiene resultados distintos.
El motivo de elegir los polígonos al azar es abrirse paso por la idea de que el compilador no puede tener
ningún conocimiento que le permita hacer las llamadas correctas en tiempo de compilación. Todas las
llamadas a dibujar( ) se hacen mediante ligadura dinámica.

EXTENSIBILIDAD

Ahora, volvamos al ejemplo de los instrumentos musicales. Debido al polimorfismo, se pueden añadir al
sistema tantos tipos como se desee sin cambiar el método afinar( ). En un programa PO0 bien diseñado, la
mayoría de métodos deberían seguir el modelo de afinar( ) y comunicarse sólo con la interfaz de la clase
base.
2. POLIMOSFISMO

Un programa así es extensible porque


se puede añadir nueva funcionalidad
heredando nuevos tipos DC datos de la
clase base común. Los métodos que
manipulan la interfaz de la clase base
no necesitarán ningún cambio si se
desea acomodarlos a las nuevas clases.
2. POLIMOSFISMO

Relación de objetos en una jerarquía

Un concepto clave en estos ejemplos es demostrar que con la herencia public un objeto de una clase

derivada puede tratarse como un objeto de su clase base. Esto permite varias manipulaciones interesantes.

Por ejemplo, un programa puede crear un arreglo de apuntadores de la clase base que apunten a objetos

de muchos tipos de clases derivadas. A pesar del hecho de que los objetos de las clases derivadas son de

distintos tipos, el compilador lo permite debido a que cada objeto de una clase derivada es un objeto de su

clase base. Sin embargo, no podemos tratar a un objeto de la clase base como un objeto de una de sus

clases derivadas.
2. POLIMOSFISMO

Por ejemplo, un empleado por comisión no es un empleado base más comisión en la jerarquía;
un empleado por comisión no tiene un miembro de datos salario base y no tiene las funciones
miembro establecer salario base y obtener salario base. La relación es un se aplica sólo de una
clase derivada a sus clases base directa e indirectas.
3. PROCESAMIENTO DE FLUJOS E/S
-

- -
3. PROCESAMIENTO DE FLUJOS E/S

INTRODUCCIÓN

La E/S en C++ ocurre en forma de flujos, que son secuencias de bytes. En las operaciones de entrada,

los bytes fluyen de un dispositivo (teclado, unidad de disco, conexión de red, etc.) a la memoria

principal. En las operaciones de salida, los bytes fluyen de la memoria principal a un dispositivo

(pantalla, impresora, unidad de disco, conexión de red, etcétera).


3. PROCESAMIENTO DE FLUJOS E/S

C++ proporciona herramientas de E/S de “bajo nivel” y de “alto nivel”. Las herramientas de E/S de bajo
nivel (E/S sin formato) especifican que se debe transferir cierto número de bytes de un dispositivo a la
memoria, o de la memoria a un dispositivo. En dichas transferencias, el byte individual es el tema de
interés. Dichas herramientas de bajo nivel proporcionan transferencias de alta velocidad y alto volumen,
pero no son especialmente convenientes para los programadores.
COMPARACIÓN DE FLUJOS

En el pasado, las bibliotecas de flujos clásicos de C++ permitían la C++ incluye las bibliotecas de flujos estándar, que permiten a los
entrada y salida de objetos char. Como por lo general un char ocupa desarrolladores crear sistemas capaces de realizar operaciones de E/S con
un byte, sólo puede representar un conjunto limitado de caracteres caracteres Unicode. Para este propósito, C++ incluye un tipo de carácter
(como los del conjunto de caracteres ASCII que utiliza la mayoría de adicional llamado wchar_t, que entre otras cosas puede almacenar
los lectores de este libro, u otros conjuntos de caracteres caracteres Unicode. El estándar de C++ también rediseñó las clases de flujos
populares). Sin embargo, muchos lenguajes utilizan alfabetos que clásicos de C++, que sólo proporcionan objetos char, como plantillas de
contienen más caracteres de los que puede representar un solo clase con especializaciones separadas para procesar caracteres de los tipos
byte. char y wchar_t, respectivamente.
CLASES Y OBJETOS DE E/S DE FLUJOS

La biblioteca iostream proporciona muchas plantillas para el manejo de las operaciones de E/S comunes.
Por ejemplo, la plantilla de clase basic_istream soporta las operaciones de entrada de flujos, la plantilla de
clase basic_ostream soporta las operaciones de salida de flujos, y la plantilla de clase basic_iostream
soporta tanto operaciones de entrada de flujos como de salida de flujos.

Cada plantilla tiene una especialización de plantilla predefinida que permite la E/S con objetos char.
3. PROCESAMIENTO DE FLUJOS E/S

Además, la biblioteca iostream proporciona un conjunto de especificadores typedef que proporcionan


alias para estas especializaciones de plantilla. El especificador typedef declara sinónimos (alias) para los
tipos de datos.

Algunas veces los programadores utilizan typedef para crear nombres de tipos más cortos o más legibles.
Por ejemplo, la instrucción:

typedef Carta *CartaPtr;


3. PROCESAMIENTO DE FLUJOS E/S

Define un nombre de tipo adicional, CartaPtr, como un sinónimo


para el tipo Carta *. Al crear un nombre mediante el uso de typedef
no se crea un tipo de datos; sólo crea un nuevo nombre de tipo. La
definición typedef istream representa una especialización de
basic_stream<char> que permite la entrada de objetos char. De
manera similar, la definición typedef ostream representa una
especialización de basic_ostream<char> que permite la salida de
objetos char.
3.1 ENTRADAS DE FLUJOS

Ahora vamos a considerar la entrada de flujos. La clase istream proporciona las herramientas de entrada con
formato y sin formato. Por lo general, el operador de extracción de flujo (>>) omite los caracteres de espacio en
blanco (como espacios, tabuladores y caracteres de nueva línea) en el flujo de entrada; más adelante veremos
cómo modificar este comportamiento.
Cada objeto flujo contiene un conjunto de bits de estado que se utilizan para controlar el estado del flujo
(es decir, aplicar formato, establecer estados de error, etc.). El operador de conversión sobrecargado void
* utiliza estos bits para determinar si debe devolver un apuntador no nulo o el apuntador nulo. La
extracción de flujo hace que se establezca el bit failbit del flujo si se introducen datos del tipo incorrecto, y
hace que se establezca el bit badbit del flujo si falla la operación.
Funciones Miembro Get y Getline

La función miembro get sin argumentos recibe como entrada un carácter del flujo designado (incluyendo
caracteres de espacio en blanco y otros caracteres no gráficos, como la secuencia de teclas que representa el
fin de archivo) y lo devuelve como el valor de la llamada a la función. Esta versión de get devuelve EOF cuando
se encuentra el fin del archivo en el flujo.
3. PROCESAMIENTO DE FLUJOS E/S
3.2 SALIDAS DE FLUJOS

La clase ostream proporciona las herramientas de salida con formato y sin formato. Las herramientas incluyen
la salida de tipos de datos estándar con el operador de inserción de flujo (<<); la salida de caracteres mediante
la función miembro put; la salida sin formato mediante la función miembro write; la salida de enteros en los
formatos decimal, octal y hexadecimal; La salida de valores de punto flotante con precisión variada, con
puntos decimales forzados, en notación científica y en notación fija; la salida de datos justificados en campos
con anchuras designadas; la salida de datos en campos rellenos con caracteres especificados y la salida de
letras mayúsculas en notación científica y notación hexadecimal.
SALIDAS DE VARIABLES CHAR *

C++ determina los tipos de datos de manera automática; una mejora sobre C. Pero esta característica algunas
veces se “interpone en el camino”. Por ejemplo, suponga que deseamos imprimir la dirección almacenada en un
apuntador char *.

El operador << se ha sobrecargado para imprimir datos de tipo char * como una cadena estilo C con terminación
nula. Para imprimir la dirección podemos convertir el valor char * en void * (esto puede hacerse con cualquier
variable apuntador).
3.2 SALIDAS DE FLUJOS
3.3 PROCESAMIENTO DE ARCHIVOS

INTRODUCCIÓN

El almacenamiento de datos en memoria es temporal. Los archivos se utilizan para la persistencia de los datos; la
retención permanente de los datos. Las computadoras almacenan archivos en dispositivos de almacenamiento
secundario como discos duros, CD, DVD, unidades flash y cintas magnéticas. En este capítulo explicaremos cómo
construir programas en C++ para crear, actualizar y procesar archivos de datos. Consideraremos los archivos
secuenciales y los archivos de acceso aleatorio. (En el capítulo 21, en inglés en el sitio web, puede comparar el
procesamiento de archivos de datos con formato y el procesamiento de archivos de datos puros, también se
examinan las técnicas para introducir y enviar datos a flujos string en vez de archivos).
ARCHIVOS Y FLUJOS

Cada archivo termina con un marcador de fin de archivo o con un número de bytes específico que se
registra en una estructura de datos administrativa, mantenida por el sistema operativo. Cuando se abre
un archivo, se crea un objeto y se asocia un flujo a ese objeto.
PLANTILLAS DE CLASES PARA PROCESAR ARCHIVOS

Para llevar a cabo el procesamiento de archivos en C++, se


deben incluir los encabezados <iostream> y <fstream>. El
encabezado <fstream> incluye las definiciones para las
plantillas de clases de flujos basic_ifstream (para las
operaciones de entrada con archivos), basic_ofstream (para
las operaciones de salida con archivos) y basic_fstream (para
las operaciones de entrada y salida con archivos).
3.3 PROCESAMIENTO DE ARCHIVOS

CREACIÓN DE UN ARCHIVO SECUENCIAL

C++ no impone una estructura sobre un archivo. Por ende, en un archivo de C++ no existe un concepto tal
como el de un “registro”. El programador debe estructurar los archivos de manera que cumplan con los
requerimientos de la aplicación. En el siguiente ejemplo veremos cómo se puede imponer una estructura
de registro simple sobre un archivo.
3.3 PROCESAMIENTO DE ARCHIVOS
Referencias bibliográficas

Bibliografía Principal
Deitel, D. y. (2012). Como programar en Java (Novena ed.). Editorial Pearson.
Bell, D. (2011). Java para Estudiantes (Sexta ed.). Pearson.
Eckel, B. (2008). Piensa en Java (Primera ed.). PAERSON.
Bibliografía Complementaria
Agustín Froufe Quintas. Java 2 Manual de usuario y tutorial. Alfaomega
Bruce Eckel. Thinking Java. Prentice Hall

También podría gustarte