Download java - Inicio

Document related concepts
no text concepts found
Transcript
Programación Orientada a
Objetos: Java vs C++
M.C. Juan Carlos Olivares Rojas
Tipos de datos
• Un dato es cualquier valor.
• Para una computadora un dato es una
secuencia finita de bits.
• Los tipos de datos ayudan a darle significado a
los datos
Tipos de datos
• Por ejemplo, la secuencia de bits 01000000
(0x40) puede representar el 64 en decimal,
o bien la letra @ todo depende del tipo de
dato.
• Los tipos de datos dependen del lenguaje
de programación y generalmente son dos:
básicos y los ADT (que se verán más
adelante).
Tipos de datos
• Los tipos de datos básicos son aquellos que se
encuentran siempre disponible en el lenguaje.
Lo más comunes son enteros, decimales,
caracteres, lógicos, entre otros.
• Los tipos de datos en Java son siempre iguales
para garantizar su portabilidad.
Tipos de datos
• Los tipos de datos de Java están especificados
en la Java Virtual Machine (JVM).
• Los tipos de datos tiene asociada una longitud
de bytes que definen su precisión y alcance.
Tipos de Datos
• Los tipos de datos básicos en Java y sus
tamaños son:
•
•
•
•
byte (1 byte)
short (2 bytes)
int (4 bytes)
long (8 bytes)
Tipos de datos
•
•
•
•
char (2 bytes)
boolean (1 byte)
float (4 bytes)
double (8 bytes)
• Para cada tipo de datos básicos existe un clase
de envoltura “wrapper” para manipularlo. Por
ejemplo: Integer
¿Cómo se compila un programa en
Java?
• Si no se cuenta con IDE (Ambiente de
Desarrollo Integrado) se puede hacer uso del
JDK (Kit de Desarrollo de Java).
• El comando javac permite compilar un archivo
con extensión .java a un archivo “ejecutable”
denominado .class
¿Cómo se compila un programa en
Java?
• Para poder ejecutar un programa en Java, una
vez que se tenga el archivo .class se debe
ejecutar el comando java seguido del nombre
del archivo.
• La edición del código se puede hacer en
cualquier editor de texto plano como el Bloc de
Notas de Windows.
Tipos de datos en C++
• Los tipos de datos básicos en C++ son:
•
•
•
•
•
char
void
short
int
long
Tipos de datos en C++
• float
• Double
• bool*
• *Sólo disponible en C++ (en C se utilizan
valores enteros: 0 es falso, diferente de 0
verdadero)
Tipos de datos en C++
• Los tipos de datos en C++ no son del mismo
tipo, ¿Por qué?
• Para comprobarlo se realizará la actividad 2.
Se utilizará la palabra reservada sizeof para
conocer el tamaño de un tipo de datos básico.
Por ejemplo: sizeof(int); devuelve el tamaño de
un entero.
Estructura de un programa en C++
//hola.cpp
/*
Programa hola mundo
*/
#include <iostream.h>
Estructura de un programa en C++
int main(void)
{
cout<<“Hola mundo”;
return 0;
}
Estructuras de Control
• Las estructuras de control se pueden clasificar
de tres tipos:
• Secuenciales
• De decisión (implican una condición)
• Repetitivas
Estructuras de Decisión
• La estructura de decisión más simples es el
if, el cual realiza una serie de acciones si se
cumple una condición o no. La sintaxis es la
siguiente:
if (condición)
{
acciones si la condición es verdadera
}
Estructuras de Decisión
else
{
acciones si la condición es falsa
}
• En C++ existe el operador ternario ?, el cual es
un if abreviado.
Estructura de Decisión
• Para casos de decisiones múltiples se suele
utilizar la estructura de control switch, la
cual su sintaxis es la siguiente:
switch (variable)
{
case 1: acciones;
break;
…
Estructuras de decisión
case n: acciones;
break;
default: acciones predeterminadas;
}
• Las opciones deben ser valores escalares y de
la misma variable
Estructuras de Repetición
• Estas estructuras permiten realizar un conjunto
de acciones hasta que una condición se
realice.
• Existen dos tipos de ciclos: precondicionales
(while y for) y postcondicionales dependiendo
de donde se evalué la condición.
Estructuras de Repetición
• El ciclo while tiene la siguiente sintaxis:
while (condición)
{
acciones a repetir;
}
• Se debe tener cuidado de no hacer ciclos
infinitos.
Estructuras de repetición
• El ciclo for permite realizar una repetición N
veces, tiene la siguiente sintaxis:
for (inicializacion; condición; incremento)
{
acciones a repetir;
}
Estructuras de repetición
• El ciclo while y for garantizan que un conjunto
de instrucciones se realicen de 0 a N veces;
mientras que un ciclo do-while garantiza que se
ejecuta al menos una vez (1 a N veces).
• En general cualquier problema se puede
resolver con cualquier tipo de ciclo.
Estructuras de repetición
• La sintaxis del ciclo do-while es la siguiente:
do
{
acciones;
} while(condicion)
;
Comparación respecto a
operaciones de Entrada y salida
• Las
operaciones
de
Entrada/Salida
generalmente no están asociadas al
lenguaje en sí por lo que es necesario
utilizar bibliotecas.
• En Java se utiliza el paquete java.io;
mientras que en C++ se utilizará iostream.h
o <iostream>
Comparación respecto a
operaciones de Entrada y salida.
• Generalmente la E/S está asociada con flujos
de archivos. La pantalla es considerada el
archivo de salida estándar, el teclado es el
archivo de entrada estándar y la pantalla es la
salida de errores estándar.
Comparación respecto a
operaciones de Entrada y salida.
• La E/S de datos depende en gran medida de la
interfaz de usuario de la aplicación. Las
interfaces más genéricas son modo texto,
modo gráfico.
• En Java la Salida se da con System.out y
algunos métodos, la Entrada con System.in
Comparación respecto a
operaciones de Entrada y salida.
• En C++ la salida se da con el objeto cout
seguido del operador de indirección de entrada
“<<”. Se puede concatenar cualquier tipo de
dato. La entrada de datos se hace con el objeto
cin y el operador de indirección de salida “>>”.
Comparación respecto a
operaciones de Entrada y salida.
• Por ejemplo, se desea obtener el área de un
triángulo por lo que se tienen que pedir al
usuario los datos de la base y la altura:
float area; int altura, base;
cout<<“Dame la base y la altura”;
cin>>base>>altura;
Comparación respecto a
operaciones de Entrada y salida.
• Se pueden pasar datos E/S por archivos (se
verán más adelante) o por argumentos de la
función principal.
• En Java dichos argumentos se guardan en la
variable args del método main.
Comparación respecto a
operaciones de Entrada y salida.
• En C++ se debe declarar la función main con
las variables int argc, char *argv[]. En donde la
primera indica el número de argumentos y la
segunda los contiene.
• El primer argumento en C++ es el nombre del
programa en Java no ocurre esto.
Comparación respecto a
operaciones de Entrada y salida.
• En Java:
public static void main(String args[]) {
System.out.println(“Argumentos:”+ args.length);
JOptionPane.showMessageDialog(null,
“Argumento 1:”+args[0]);
}
Comparación respecto a
operaciones de Entrada y salida.
• En C++:
int main(int argc, char *argv[]){
if(argc!=2)
exit(-1);
cout<<“Argumento 1: ”<<argv[0];
return 0;
}
Entrada/Salida en C
• La E/S en C es más complicada que la de C++,
para hacer uso de ella se debe incluir la
biblioteca stdio.h
• La función básica de salida es printf, la cual
debe de manejar distintos parámetros para el
tipo de datos; la entrada se da con la función
scanf.
Entrada/Salida en C
int altura, base;
float area;
printf(“Introduce la base y la altura”);
scanf(“%d%d”, &altura, &base);
area = base * altura /2;
printf(“El resultado es:”);
Actividad 1
• El valor del exponente e, se calcula de la
siguiente forma:
• E=1+1/2+1/3+…+1/n
• Tendiendo a 2.71. Realizar un programa en
Java y C++ que pida como argumento el
límite máximo de precisión. ¿A partir de que
número se obtiene 2.71?
Comparación respecto a la
definición, creación y uso de
clases y objetos
• En Java todo debe de estar dentro de una
clase, en C++ no es necesario.
• En Java los archivos se deben llamar como se
nombró a la clase, en C++ no.
Comparación respecto a la
definición, creación y uso de
clases y objetos
• En Java dentro de cada clase se deben incluir
la definición de sus métodos y atributos, en
C++ no es necesario.
• En C++ existe la herencia múltiple, en Java no.
En C++ las clases heredan con el operador “:”
en Java con “extends”
Comparación respecto a la
definición, creación y uso de
clases y objetos.
• Las clases para poderse utilizar se necesita
de la creación de objetos, lo cual se hace a
través del operador new en Java, en C++
no es necesario sólo que se pida memoria
dinámica para el objeto.
• El uso es el mismo, con el operador “.” se
hacen a los miembros de la clase.
Comparación respecto a la
definición y uso de métodos y
parametrización.
• Para la definición de atributos y métodos Java
dispone de modificadores de alcance para cada
elemento individual: public, private y protected.
En C++ se utilizan de forma global siendo
privado todo lo que está dentro de la clase. A
esto en POO se le llama encapsulación.
Comparación respecto a la
definición y uso de métodos y
parametrización.
• Los métodos en C++ se pueden definir
fuera de una clase con el operador de
alcance “::”.
• Los parámetros se pueden utilizar sin
ningún problema. La palabra clave this en
C++ se utiliza para hacer referencia al
mismo objeto.
Comparación respecto a la
definición y uso de métodos y
parametrización.
//Clase.h
class Triangulo: angulo {
int altura, base;
float area;
public:
void calcularArea(void);
void setAltura(int valor);
}
Comparación respecto a la
definición y uso de métodos y
parametrización.
//clase.c
void Triangulo::calcularArea(void){
Area = base * altura /2;
}
Void Triangulo::setAltura(int valor){
altura = valor;
}
Arreglos Unidimensionales
• Los arreglos son una colección homogénea
de datos.
• Los datos pueden ser básicos o bien
definidos por el usuario.
• La ventaja de utilizar arreglos es que
permite manejar múltiples datos como si
fuera una unidad.
Arreglos Unidimensionales
• Los arreglos pueden tener varias dimensiones.
Si son de una sola dimensión se les llama
unidimensionales o vectores.
• Para definir y utilizar un arreglo se utiliza el
operador [] que delimita el tamaño de un
arreglo y sirve para acceder a un elemento
particular.
Arreglos Unidimensionales
• Los arreglos no son otra cosa
direcciones consecutiva de memoria.
que
• El uso de arreglos en C/C++ está
fuertemente relacionado con el uso de
punteros y la aritmética de punteros. En
donde el nombre del arreglo representa una
dirección base y el índice del arreglo un
desplazamiento.
Arreglos Unidimensionales
• La siguiente sintaxis se utiliza para definir un
arreglo: tipo nombre[tamaño];
• float calificaciones[10]; //Define un arreglo de
decimales de tamaño 10
• En C/C++ se puede utilizar directamente el
arreglo, en Java hay que instanciarlo.
Arreglos Unidimensionales
• Para crear un arreglo en Java se debe utilizar
el operador new:
• calificaciones = new float[10];
• En C++ se utilizaría esta instrucción para
declarar un arreglo con memoria dinámica.
Arreglos Unidimensionales
• Para acceder a un elemento del arreglo
simplemente se utiliza el subíndice:
• calificaciones[3]=100; // colocaría un 100 al
tercer elemento del arreglo
• En Java se puede conocer el tamaño de un
arreglo con la propiedad length.
Arreglos Unidimensionales
• System.out.println(“”+calificaciones.length);
//imprimiría 10
• En C/C++ es fácil salirse de los límites de los
arreglos, en Java no, ya que marca un error en
tiempo de compilación sino se atrapan todas
las excepciones.
Actividad 2
• Realizar un programa en Java que permita
calcular el promedio de 10 materias y decidir si
se tiene derecho a una semana más de faltas
(si el promedio >= 83). Encontrar la calificación
mayor y menor de la lista.
Ordenamiento
• Una de las partes más interesantes en los
arreglos después de las búsquedas son los
ordenamientos.
• Si se tiene un arreglo ordenado las búsquedas
se simplifican, el problema es ordenar el
arreglo.
Ordenamiento
• Existen varios métodos de ordenamiento,
cada uno con sus respectivas ventajas y
desventajas.
• Los métodos tratados son 3: Burbuja,
Selección e Inserción, pero existen una
gran
variedad
de
algoritmos
de
ordenamiento: Shell, Heap, Tournament,
Quicksort, Mergesort, Radixsort, …
Ordenamiento por Burbuja
• El Bubblesort es quizás el algoritmo más
simple de ordenamiento. Basa su filosofía
en cada iteración colocar el elemento más
grande o más pequeño (dependiendo del
criterio de selección) en la primera posición
de tiempo.
• La complejidad del algoritmo es O(n2) en el
peor de los casos y de O(n) en el caso
promedio.
Ordenamiento por Burbuja
• La complejidad de un algoritmo determina
que tan rápido es el algoritmo. Se expresa
generalmente con una función matemática
que permite comprender como trabaja un
algoritmo.
• La complejidad está medida en tres
situaciones: mejor de los casos, caso
promedio y en el peor de los casos.
Ordenamiento por Inserción
• Este algoritmo tiene su fundamento en como
trabajamos los humanos para ordenar las
cosas: nos basamos en cosas ya ordenadas y
simplemente las colocamos en su nuevo orden.
• Es parecido cuando ordenamos una carta en
un juego de Pocker.
Ordenamiento por Inserción
• Su complejidad también es de O(n2) en el caso
promedio.
• Asume a que el algoritmo ya está ordenado,
por lo que es útil cuando se agrega un nuevo
elemento. ¿Qué se hace cuando se está
desordenado?
Ordenamiento por Selección
• Tiene una complejidad de O(n2).
• Consiste en encontrar el valor máximo o
mínimo del arreglo e intercambiarlo en la
primera posición, después se realiza el
mismo proceso para los n-1 elementos
faltantes… se repite el procedimiento hasta
terminar con los elementos del arreglo.
Comparativa de Algoritmos de
Ordenamiento
Burbuja
Inserción
Selección
String
• Las cadenas o “strings” son uno de los tipos de
datos básicos que tiene cada uno de los
lenguajes de programación.
• En el caso de C/C++ las cadenas son un
arreglo de caracteres en donde la última
posición es un carácter especial, el terminal
nulo ‘\0’.
String
• Las cadenas en C/C++ se pueden manejar
como cualquier otro arreglo, pero ya existen
algunos
métodos
predeterminados
(definidos en string.h) para las tareas
básicas:
• Copiar cadenas: strcpy(destino, origen);
• Comparar cadenas: strcmp(cad1, cad2) //0
si son iguales, > 0 cad1 mayor, <0 cad2
mayor
String
• strlen(cad) //devuelve la longitud
• strset(s, c) //inicializa una cadena con el
carácter c
• El modificador en C para leer e imprimir
cadenas es %s.
• La función gets permite obtener cadenas
con espacios en C/C++
String
• En C++ se cuenta con el objeto string definido
en la bilioteca string del espacio de nombres
estándar.
• El cual puede copiarse y concatenarse cadenas
de manera directa. Tiene la propiedad
tamaño(length), el método assign, at(),
append(), entre otros.
String
• En Java también existe la clase String, la cual
tiene métodos muy parecidos a su clase
homónima en C++.
• Las cadenas en Java tienen métodos para
comparar (compare()), para manejo de
subcadenas (substr()), entre otros métodos.
String
• Las cadenas o “strings” son uno de los tipos de
datos básicos que tiene cada uno de los
lenguajes de programación.
• En el caso de C/C++ las cadenas son un
arreglo de caracteres en donde la última
posición es un carácter especial, el terminal
nulo ‘\0’.
String
• Las cadenas en C/C++ se pueden manejar
como cualquier otro arreglo, pero ya existen
algunos
métodos
predeterminados
(definidos en string.h) para las tareas
básicas:
• Copiar cadenas: strcpy(destino, origen);
• Comparar cadenas: strcmp(cad1, cad2) //0
si son iguales, > 0 cad1 mayor, <0 cad2
mayor
String
• strlen(cad) //devuelve la longitud
• strset(s, c) //inicializa una cadena con el
carácter c
• El modificador en C para leer e imprimir
cadenas es %s.
• La función gets permite obtener cadenas
con espacios en C/C++
String
• En C++ se cuenta con el objeto string definido
en la bilioteca string del espacio de nombres
estándar.
• El cual puede copiarse y concatenarse cadenas
de manera directa. Tiene la propiedad
tamaño(length), el método assign, at(),
append(), entre otros.
String
• En Java también existe la clase String, la cual
tiene métodos muy parecidos a su clase
homónima en C++.
• Las cadenas en Java tienen métodos para
comparar (compare()), para manejo de
subcadenas (substr()), entre otros métodos.
Arreglos Bidimensionales
• Los arreglos bidimensionales mejor conocidos
como matrices o tablas son aquellos que tienen
dos dimensiones.
• Son ampliamente utilizados en el mundo de la
computación para resolver muchos problemas
matemáticos.
Arreglos Bidimensionales
• Para poder trabajar con ellos se necesitan
dos índices (si se tuvieran n dimensiones,
se ocuparía n índices), uno para las filas y
otro para las columnas.
• En general se pueden aplicar los mismos
algoritmos
que
en
arreglos
unidimensionales, variando sólo la forma de
recorrer el arreglo.
Arreglos Bidimensionales
• Se declaran de la siguiente forma:
// f= Filas c=Columnas
int a[f][c];
for(int i=0;i<f;i++)
for(int j=0; j<c;j++)
a[i][j]=0;
Excepción
• El manejo de errores es una de las cosas más
importantes de cualquier lenguaje de
programación y de cualquier programa
elaborado con estos.
• Los lenguajes orientados a objetos nos
permiten un mejor control de los errores
ocurridos a través del uso de excepciones
Excepción
• Primero aparecieron las excepciones en Java y
hasta después en C++. C/C++ se han
caracterizado por el manejo de errores de muy
bajo nivel.
• Una excepción no es otra cosa que una clase
que nos sirve para manipular errores.
Excepciones
• Las excepciones se manejan de manera
muy similar en Java y en C++.
• En C no existen excepciones y
generalmente se asocian valores negativos
a los errores y se procesan.
• Se debe indicar el código a validar con la
instrucción try.
Excepciones
• Las excepciones se atrapan con la palabra
clave catch, indicando cual es la excepción a
atrapar.
• En Java existe la clase genérica Exception que
sirve para atrapar cualquier tipo. Lo
recomendable es utilizar la clase específica
para atrapar la excepción.
Excepciones
• Se puede utilizar la palabra clave throws para
lanzar una excepción; es decir, para producirla.
• Lanzar excepciones nos permite generar
nuestras propias excepciones para después
poder utilizarlas y manejar de forma elegante
los errores ocurridos.
Excepciones
• También existe la palabra reservada finally que
permite ejecutar un bloque de instrucciones
ocurra o no la excepción.
• En algunas ocasiones será necesario atrapar
una excepción en particular en tiempo de
diseño, sino de lo contrario nuestros programas
no compilaran.
Excepciones
try {
resultado = a/b;
}
catch (Exception e) {
System.out.println(“Error al dividir”);
e.printStackTrace();
}
Excepciones
catch (OtraExcepcion e2) {
…
}
finally
{
System.out.println();
}
Excepciones
• Para generar nuestras propias excepciones
se crea una clase que hereda de algún tipo
de excepción:
public class ExcepcionDivision
Exception {
public ExcepcionDivision() {
super(“Error al dividir entre cero”);
}
}
extends
Excepciones
• Si se quiere lanzar la excepción en un
método, este quedaría así:
Public
int
calcular(int
a)
ExcepcionDivision {
if(divisor==0)
throw new ExcepcionDivision;
….
}
}
throws
Excepciones
• Algunos ejemplos de excepciones son:
•
•
•
•
•
•
ClassNotFoundException
ArithmeticException
IndexOutofBoundsException
NullPointerException
RuntimeException
IOException
Actividad 2
• Realización de un formulario en Java que
sirva de base para el calculo de las raíces de
una ecuación cuadrada.
• El programa deberá utilizar excepciones y
manejarlas de manera adecuada.
C++
• En C++ el manejo de archivos cambia
drásticamente dado que se manejan clases.
• Se encuentran definidas en la biblioteca
<fstream> generalmente se manejan tres
clases ifstream para entrada, ofstream para
salida y fstream para entrada y salida.
Archivos en C++
• Los objetos genéricos de <iostream> (cin, cout,
cerr y clog) son considerados flujos o archivos.
• Se siguen realizando las mismas operaciones
sobre archivos: abrir, leer/escribir, cerrar
archivo con algunas características.
Ejemplo
//Archivo de salida
#include <cstdlib>
#include <iostream>
#include <fstream>
using namespace std;
int main(int argc, char *argv[])
{
Ejemplo
string cadena;
unsigned short int edad;
ofstream archivo("archivo.txt", ios::out);
if(!archivo) {
cerr<<"El archivo no pudo crearse";
exit(-1);
}
Ejemplo
//lectura de datos desde la terminal
cout<<"Introduce tu nombre y edad";
cin>>cadena>>edad;
archivo<<cadena<<" "<<edad;
system("PAUSE");
return EXIT_SUCCESS;
}
Archivos en C++
• Se abre un archivo al crear un objeto ofstream,
se tienen los siguientes parametros:
•
•
•
•
ios::app //a
ios::ate //a+
ios:in //r
ios:out //w
Archivos en C++
• ios::nocreate //si no existe, falla
• Ios::noreplace //si existe falla
• El operador de fin de archivo generalmente
se representa con Ctrl+z o Ctrl+d.
• Se puede cerrar un archivo con el método
close(), si no se utiliza al finalizar el
programa el destructor lo hace.
Archivos en C++
//Para lectura de archivos
string nombre;
unsigned short edad;
ifstream archivo(“archivo.txt”, ios::in)
archivo>>nombre>>edad;
cout<<“nombre:”<<nombre<<“ edad:”<< edad;
Archivos
• Por la forma de acceder a los archivos estos se
clasifican en acceso secuencial y directo.
• Generalmente cuando se maneja archivos de
texto el manejo es secuencial y cuando son
binarios se pueden acceder de manera
aleatoria.
Archivos
• Se puede utilizar el método write() de ofstream
para escribir en modo binario y el método read
de ifstream para leer en modo binario.
• Se puede utilizar el método seekp() para
desplazarse de manera aleatoria por todo el
archivo.
Archivos en C++
• Otros métodos que se pueden utilizar es el
método open() para abrir, fail() para comprobar
si se abrió correctamente y eof() para validar fin
de archivo.
• Al abrir un archivo se puede omitir su
modificador y se le asignan los permisos por
default.
Archivos en C++
• Se pueden agregar diversos modificadores de
acceso: ios:in | ios:out, para lectura y escritura
a la vez.
Archivos en Java
• Los archivos en Java se manejan como en
cualquier lenguaje, con la ventaja de que el
mismo código sirve para todas las plataformas
de cómputo.
• Las APIs para el manejo de archivos se
encuentran en el paquete java.io.*
Archivos en Java
• Para abrir archivos para lectura se utiliza la
clase FileInputStream que a su vez deriva de
InputStream.
• Para abrir archivos para escritura se utiliza la
clase FileOutputStream que a su vez hereda de
la clase OutputStream.
Archivos en Java
• Para realizar la E/S de tipos de datos primitivos
se utiliza la clase DataInputStream y
DataOutputStream.
• Otras clases utilizadas para la manipulación de
archivos
son:
File,
FileDescriptor,
BufferedInputStream, BufferedOutputStream y
RandomAccessFile
Archivos
• Las
clases
DataInputStream
y
RandomAccessFile implementan la interfaz
DataInput por lo cual se tienen métodos
como los siguientes: read(), readBoolean(),
readByte(), readInt(), …
• Las
calses
DataOutputStream
y
RandomAccessFile implementa la interfaz
DataOutput.
Archivos en Java
• La interfaz Dataoutput tiene métodos como los
siguientes:
flush(),
size(),
write(),
writeBoolean(), writeFloat(), …
• BufferedInputStream y BufferedOutputStream
utilizan buffers para eficientar el proceso de
lectura/escritura en archivos.
Archivos en Java
• Como se crea un archivo
• DataOutputStream archivo;
• Archivo
=
new
DataOputStream(new
FileOutputStream(“archivo.dat”));
• Se debe atrapar la excepción IOException
Archivos en Java
• Se opera con el archivo leyendo o
escribiendo y después se debe cerrar con el
método close().
• A la hora de leer datos de un archivo se
debe atrapar la excepción EOFException.
• Se puede hacer esto para leer datos desde
la consola.
Archivos en Java
• Se
recomienda
utilizar
BufferedInputReader para manejar
archivo de entrada de la consola.
un
el
• La clase RandomAccessFile permite
manejar archivos de manera muy similar al
lenguaje C.
Archivos en Java
• archivo
=
RandomAccessFile(“archivo.dat”, “rw”);
new
• Se utiliza el método write con el nombre de un
objeto.
• La clase File tiene métodos como: canRead(),
exists(), isFile(), isDirectory(),
Archivos en Java
• getName(), getPath(), length(), lastModified(),
list(), …
• Realizar el programa Agenda con Archivos en
Java
Apuntadores en C++.
• Los apuntadores son variables que almacenan
direcciones en lugar de datos.
• Los apuntadores permiten apuntar hacia
distintas localidades de memoria, por lo que se
utilizan para generar memoria dinámica.
Apuntadores en C++
• Los apuntadores pueden ser de cualquier tipo,
se declaran anteponiendo un *:
• int *puntero; //apuntador a un entero
• char *cad; //apuntador a caractér
• void *puntero; //puntero a cualquier tipo de dato
Relación entre arreglos y
apuntadores en C++.
• La relación que existe entre un arreglo y un
apuntador es que el nombre de un arreglo
representa una dirección de memoria y los
subíndices representan un desplazamiento.
• Las cadenas son arreglos de caracteres
(apuntador a un carácter)
Aritmética de apuntadores en C++
• La aritmética de apuntadores significa
poder desplazarse a través de la memoria.
• Sólo se pueden utilizar los operadores +,-,
++, -- y otros operadores de manera
indirecta.
• El operador & se utiliza para obtener la
dirección de una variable.
Memoria estática y dinámica
• Los apuntadores se utilizan para crear memoria
dinámica.
• De manera predeterminada, las variables se
crean con memoria estática en lo que se
conoce como tiempo de ejecución, por eso se
debe de definir un tamaño máximo en los
arreglos.
Memoria Dinámica
• La memoria dinámica se puede crear
simplemente teniendo un tipo de dato puntero.
• Por ejemplo para declarar un arreglo de
enteros dinámicos, quedaría así:
• int *arreglo; //no se especifica tamaño
Memoria Dinámica
• En C se utiliza la función malloc para pedir
memoria y free para liberarla.
• arreglo = (int *) malloc(N * sizeof(int));
• free(arreglo);
• En Java no existe como tal los punteros pero
se puede utilizar memoria dinámica.
Memoria Dinámica
• En C++ al igual que Java se utiliza el operador
new para pedir memoria dinámica. De hecho
en Java los arreglos deben crearse con el
operador new:
• int a[5] = new int[5]; //Java
• int a[] = new int[N]; //C++
Memoria Dinámica
• delete [] a;
• En Java no existe el concepto de liberar
memoria ya que se hace de manera
automática con el recolector de basura.
• La memoria dinámica sirve para crear otros
tipos de ADT más especializados como
listas, pilas, colas, árboles, etc.
Memoria Dinámica
• Al borrar un elemento se regresa la memoria
que se pidió, por eso es importante liberar la
memoria, ya que si no se hace se pierde ese
pedazo.
• Si se crea memoria dinámica para un objeto se
puede llamar a su constructor para que lo
inicialice.
Creación y uso de arreglos y
objetos dinámicos en C++.
Comparación con JAVA.
• En Java no existe el concepto de puntero. Se
pueden crear memoria dinámica.
• En objetos al liberar memoria se invoca de
manera automática al destructor en C++ y al
método finalize() y variantes en Java.
Actividad
• Realizar un programa que cree un arreglo con
la mayor cantidad de números primos.
• El usuario deberá introducir el tamaño del
arreglo y este deberá hacerse a través de
memoria dinámica. El límite lo marcará el
tamaño de la memoria disponible.
Implementación de funciones libres
• C++ es un lenguaje híbrido que permite
mezclar POO y Programación Estructurada.
• Por este motivo se pueden tener funciones sin
necesidad de agruparlas en clases.
• Las funciones pueden recibir y devolver
apuntadores como argumentos.
Implementación de Funciones
Libres
• Cuando se utilizan parámetros del tipo puntero
se dicen que los argumentos se pasan por
referencia, de este modo se pueden modificar
directamente.
• Cuando se omiten punteros, los argumentos
son por valor y sólo se copia en la función el
valor de los argumentos.
Actividad
• Realizar un programa que dado diferentes
arreglos de distintos tamaños encuentre el
mayor de n números. El código de mayor debe
de ser una función.
• Modificar el programa anterior para que el
arreglo pueda ser dinámico de acuerdo al
tamaño que indique el usuario.
Uso del typedef y el struct en C++
• Una estructura es un tipo de datos complejos
que puede contener diversos tipos de datos
simples formando una unidad.
• En otros lenguajes reciben el nombre de
registros. Las estructuras se manejan en
programación estructurada.
Uso del typedef y struct en C++
• Las estructuras en C/C++ se crean con la
palabra clave struct seguida del nombre de
la estructura:
struct paciente {
unsigned int ID;
unsigned short edad;
char nombre[40];
};
Uso del typedef y struct en C++
• Una estructura se asemeja mucho a una
clase en lo que respecta a los atributos de
los objetos.
• De hecho en C++ (pero no en C) las
estructuras pueden anidar funciones. El
modificador por default en una estructura es
public, mientras que en una clase es
private.
Uso del typedef y struct en C++
• Una vez declarada la estructura (se
recomienda realizarla fuera de cualquier
función de manera global y en un archivo de
encabezado .h) se pueden crear variables de
este nuevo ADT:
• struct paciente p;
Uso del typedef y struct en C++
• Para evitar el repetir varias veces la palabra
struct y el nombre de la estructura se puede
crear un alias mas simple utilizando la
palabra reservada typedef que significa
definición de tipo.
• typedef struct paciente P; //alias
• P p; //Declara una variable de tipo paciente.
Actividad
• Realizar un programa que pida los datos de un
artículo
de
cómputo:
nombre,
precio,
descripción, número de identificación.
• Guardar esos
estructuras.
datos
en
un
arreglo
• Leer y escribir dichos valores en un archivo
de
Recursividad como herramienta
para el control de ciclos
• La recursividad es una manera elegante de
resolver problemas.
• Una función se dice que es recursiva cuando
se invoca así misma. Ejemplo el factorial de un
número, las torres de hannoi, la serie de
fibonacci, etc.
Recursividad
• N! = N * (N-1)!
• 5! = 5 * 4!
• Fibo(5) = Fibo(4) + Fibo(3)
• La recursividad nos permite resolver problemas
que parecen ser muy complejos de manera
sencilla.
Recursividad
• Todo programa recursivo puede ser resuelto a
través de ciclos pero puede que esta solución
sea muy compleja.
• Toda función recursiva debe de tener dos
características básicas: un caso base y el caso
recursivo.
Recursividad
• Ojo: si no se cuenta con un caso base el
programa se puede ciclar de manera
indefinida provocando que el programa o el
sistema operativo colapsen.
• La recursividad de manera interna trabaja
con memoria dinámica, se utilizan pilas
para guardar los valores anteriores de las
funciones recursivas.
Recursividad
• La gran desventaja de las funciones recursivas
es que son ampliamente consumidoras de
memoria.
• Todo programa recursivo puede implementarse
con pilas. La recursividad trata de sacar
provecho al principio de divide y vencerás.
Actividad
• Realizar los siguientes programas de forma
recursiva:
• Factorial
• Serie de Fibonnaci,
• Multiplicación de dos números
Concepto de nodo y
encadenamiento
• Las listas ligadas es una de las estructuras de
datos definidas por el usuario más empleada.
• Las listas tienen la característica de que son
dinámicas por este motivo se hace uso de
memoria dinámica, apuntadores (C/C++) y
referencias (Java/C++).
Concepto de Nodo y
Encadenamiento
• El nodo es el elemento fundamental de la lista.
• Si una lista no tiene nodos se dice que está
vacía.
• Las listas no tienen un tamaño máximo
predeterminado.
Concepto de Nodo y
Encadenamiento
• Un nodo no es otra cosa que una estructura
con los datos que nos van a interesar
trabajar. El nodo contiene además al menos
un enlace simple (listas ligadas) o enlaces
dobles (lista doblemente ligada).
• De manera interna la lista puede tener uno
o más apuntadores a los nodos de la lista
(generalmente: inicio, fin y actual)
Concepto de Nodo y
Encadenamiento
• Los principales tipos de lista son dos
dependiendo de la forma en como se accedan
a los nodos:
• Cola (FIFO, Fist In First Out) en donde por un
extremo se atienden clientes y por el otro van
llegado.
Concepto de Nodo y
Encadenamiento
• Pila (LIFO, Last In First Out) en este tipo de
lista sólo se trabaja con un extremo, el llamado
cima de la pila.
• El encadenamiento consiste en enlazar nodo
con
nodo
para
poder
ligarlos.
Sin
encadenamiento no se puede tener una lista
ligada.
Concepto de Nodo y
Encadenamiento
• Generalmente el inicio y el fin de una lista
están ligadas hacia un nodo vacío.
struct nodo {
int valor;
struct nodo *izq;
struct nodo *der;
}
Concepto de Nodo y
Encadenamiento
• Las listas circulares son aquellas que el fin de
la lista apunta hacia el inicio.
• Las áreas de aplicación de las listas son muy
diversas. Se utilizan para ordenamiento,
búsquedas, almacenamiento de información,
etc.
Operaciones de inserción,
desplegado y eliminación de nodos
de una lista
• Las operaciones básicas de una lista consiste
en agregar elementos, borrarlos y listarlos.
• Cada una de estas operaciones debe
considerar en que parte de la lista se hace:
inicio, en medio o fin.
Operaciones con Lista
• Lenguajes como Java tienen de manera
predeterminada objetos del tipo Lista u
objetos derivados de lista.
• Otras operaciones consiste en determinar si
la lista está vacía.
• Estructuras como árboles y grafos siguen el
mismo principio.
Operaciones con Lista
• Cuando se agrega un nuevo elemento lo
primero que hay que realizar es crear el
nuevo nodo, identificar en que parte debe
de ir, actualizar los apuntadores al nuevo
nodo, considerar los casos especiales.
• Al borrar se sigue el procedimiento
contrario, se actualizan apuntadores,
desligando el nodo y liberando memoria.
Aplicación integradora de
conceptos del curso
• Realizar un programa que permita sumar
números enteros muy grandes. Cada dígito
debe pertenecer a un nodo. Se ordenan los
nodos para ir sumando el número menos
significativo. El resultado de la operación se
guarda en otra lista.
Paquete de Utilidades
• Java cuenta con una serie de APIs para el
manejo de estructura de datos básicas, dichos
componentes se encuentran en el paquete
java.util
• La clase Vector permite tener un arreglo de
cualquier tipo de dato, el cual crece de manera
automática.
Vector
• En el constructor se puede indicar el tamaño
inicial del vector:
• Vector v = new Vector(10);
• De manera predeterminada
conforme al tamaño asignado.
este
crece
Vector
• Para agregar elementos se utiliza el método
addElement(Object).
• Para eliminar elementos se utiliza el método
removeElement(Object);
• Para obtener el primer elemento: firstElement();
Vector
• Para obtener el último elemento: lastElement();
• Para verificar si se encuentra vacío: isEmpty();
• Para verificar si se encuentra un elemento en
particular: contains(Object);
Vector
• indexOf(Object); sirve para encontrar la
posición de un objeto en particular.
• trimToSize(); permite recortar el tamaño de
un vector hasta donde se tenga el último
elemento.
• size(); indica el tamaño actual y el método
capacity(); hasta donde puede crecer el
vector sin duplicarse.
Enumeration
• El objeto Enumeration permite tener un objeto
iterador para la manipulación de muchos tipos
de objetos.
• Enumeration enum = v.elements();
• enum.hasMoreElements(); permite saber si se
tienen más elementos.
Enumeration
• enum.nextElement(); obtiene el siguiente
elemento si existe, de lo contrario devuelve una
Excepción: NoSuchElementException.
• Tambien Java cuenta con una clase Pila:
• Stack s = new Stack();
Enumeration
• Se cuenta con los siguientes métodos:
•
•
•
•
•
s.push(obj); para agregar elementos
s.pop(); para quitar elementos
s.peek(); para observar el elemento de la cima
s.empty(); determina si la pila está vacía
s.search(obj); para buscar un elemento.
Dictionary-Hashtable
• La clase Dictionary es una clase abstracta (no
se pueden crear objetos de dicha clase) que
sirve de interfaz a la clase Hashtable.
• Las tablas permiten almacenar una clave y un
valor para ser utilizadas posteriormente.
Hashtable
• Se construye un objeto como:
• Hashtable tabla = new Hashtable();
• Los métodos de dicha clase son:
• Object val = tabla.put(nombre, empleado);
en donde nombre es un String y empleado
un objeto.
Hashtable
• Si no hay un valor para la clave especificada se
devuelve un null. Si ya existe una clave/objeto
se devuelve el mismo objeto.
• Object val = tabla.get(clave); ayuda a recuperar
un elemento en particular.
Hashtable
• Para eliminar elementos se utiliza:
• Object val = tabla.remove(clave); si no se
puede eliminar el elemento se devuelve null, en
caso contrario se devuelve la referencia del
elemento.
• tabla.isEmpty(); nos sirve para determinar si
está vacía la tabla.
Hashtable
• tabla.containsKey(clave); para determinar si
se cuenta con esa clave en el diccionario.
• tabla.clear(); vacía toda la tabla
• tabla.elements(); para obtener un objeto
Enumeration.
tabla.keys();
tambien
devuelve una enumeración pero de las
claves nada más.
Sobrecarga de operadores en C++
• La sobrecarga de operadores es una forma
más de polimorfismo.
• La sobrecarga de operadores permite definir
para una clase un método especial, por
ejemplo la clase string sobre carga el operador
+ para concatenar cadenas.
Sobrecarga de operadores
• Los operadores que se pueden sobrecargar
son: +, -, *, /, %, ^, &, |, _, ', =, <, >, <=, >=, ++,
--, <<, >>, ==, %%, ||, +=, -=, *=, /=, %=, &=, |=,
<<=, >>=, [ ], ( ), ->, ->*, new, delete
• Los operadores que no se pueden sobrecargar
son: ., ::, ?:, sizeof
Sobrecarga de Operadores
• Existen algunos operadores como el = que ya
se encuentran sobrecargados de manera
nativa. En el caso del = compara objetos en
base a sus referencias.
• Antes de ver la sobrecarga de operadores se
verá la sobrecarga de funciones para entender
el concepto.
Sobrecarga de funciones
• Un método o función se dice que está
sobrecargado
cuando
para
el
mismo
identificador se pueden realizar dos o más
funciones. Por ejemplo:
int suma(int a, int b) {
return a+b;
}
Sobrecarga de funciones
double suma(double a, double b) {
return a+b;
}
• Se puede invocar la función suma de dos
formas distintas:
• int c = suma(10, 3);
• double d = suma(10.3, 5.1);
Sobrecarga de operadores
• La única restricción de la sobrecarga de
operadores es que no se puede cambiar la
aridad de los operadores; es decir, si el + es
binario, se sigue manejando de la misma
forma.
• Complex&
Complex::operator[](unsigned
int i) { return data[i]; }
Sobrecarga de operadores
class Vector {
public:
float x, y;
Vector operator+ (Vector v) {
Vector resultado;
resultado.x = x + v.x;
resultado.y = y + v.y;
return resultado;
}
};
Sobrecarga de operadores en Java
• Java no soporta sobrecarga de operadores.
Los
únicos
casos
de
operadores
sobrecargados con una operación especial
(definido por el sistema no por los
programadores) son el operador = para copia,
para == igualdad de referencias y + para la
concatenación de cadenas o elementos.
Uso de plantillas (templates) en
C++
• Las plantillas nos permite hacer genéricos los
tipos de datos abstractos; es decir, nos
permiten definir una clase que funcione con
cualquier tipo de datos, por ejemplo una lista
puede ser de cualquier cosa.
• template <class tipo_dato>
• class clase { …… };
Plantillas
int max(int x, int y) {
return (x < y) ? y : x;
}
float max(float x, float y) {
return (x < y) ? y : x;
}
Plantillas
template <typename T>
T max(T x, T y) {
return (x < y) ? y : x;
}
• Cuando se trata de funciones no hay diferencia
entre los atributos typename y class
Plantillas
• Los objetos parametrizados se crean con:
una_clase<int> x;
• Java permite genericidad pero es mucho más
básica que en C++.
public interface Iterator<E> { E next();
boolean hasNext(); }
Manejo congruente de parámetros
con objetos dinámicos y atributos
dinámicos
• Se debe tener mucho cuidado al momento de
crear objetos de manera dinámica que a su vez
reciba como argumentos atributos también
dinámicos.
• Se debe limpiar de la memoria todos los
objetos que no se necesiten.
Herencia en C++: Definición, clases
abstractas y métodos virtuales
• La herencia es un mecanismo que permite la
reutilización de componentes. Se basa en el
principio de que los objetos en la vida real
heredan ciertos atributos y comportamientos de
sus padres.
• La herencia en C++ puede ser múltiple.
Herencia
//Clase Padre
class punto {
protected:
int x, y
public:
int getX();
int getY();
};
Herencia
//Clase hija
class linea:punto {
private:
int x1, y1;
public:
void dibujar();
};
Clases Abstractas
• Son aquellas clases que sólo sirven para hacer
generalización; es decir, sirven de clase base
más no se instancian objetos de dicha clase.
• Las clases abstractas son el equivalente a las
interfaces en Java.
Métodos Virtuales
• Son los métodos que se definen en las
clases abstractas y que se implementan en
cada clase hija.
• Los métodos virtuales se caracterizan por
que se ligan en memoria; es decir, se
mandan llamar desde un puntero a la clase
abstracta y de manera dinámica se ejecuta
el método que corresponde al objeto actual.
¿Preguntas, dudas y comentarios?