Documentos de Académico
Documentos de Profesional
Documentos de Cultura
PROGRAMACIÓN AVANZADA I
UV
-
I PARCIAL
PROGRAMACION AVANZADA I
-
I PARCIAL
-
- -
Objetivo General de la asignatura:
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:
• 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:
Principales lenguajes
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.
- -
2. POLIMOSFISMO
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 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
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:
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
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 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
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
Algunas veces los programadores utilizan typedef para crear nombres de tipos más cortos o más legibles.
Por ejemplo, la instrucción:
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
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