1. ESCUELA POLITÉCNICA NACIONAL
INGENIERÍA EN ELECTRÓNICA Y
REDES DE INFORMACIÓN
TEMA DE PROYECTO
MUSICA
INTEGRANTES:
Aguayo César
Cárdenas Cristel
Suasnavas Carmen
PROFESOR:
ING. RODRIGO CHANCUSIG
2. INDICE
1. TEMA........... ........... ........... ........... ................................................................................................................... 2
2. OBJETIVOS……………………………………………………………………………………………………...2
3.ALCANCE ……………………………………………………………………………………………………….2
4.SUSTENTACIÓN TEÓRICA……………………………………………………………………………….……3
Eclipse…………………………………………………………………………………………..…..…….3
Diagrama UML……………………………………………………………………………………….…..4
Diagrama de Clases ………………………………………………………………………..…...5
Algunos Elementos Utilizados ………………………………………………………………..…………9
Interfaces …………………………………………………………………………..…………10
Variables y Métodos estáticos …………………………………………………….…………11
Integer …………………………………………………………………………………………..………14
Excepciones ………………………………………………………………………………...…………..15
Actualización de información…………………………………………………….……………………..23
Archivos de texto…………………………………………………………………………………..……24
5.CONCLUSIONES Y RECOMENDACIONES ………………………………………………….…….…….…25
6.REFERENCIAS Y BIBLIOGRAFÍA……………………………………………………………………...….…26
ESCUELA POLITÉCNICA NACIONAL
INGENIERÍA ELECTRÓNICA Y REDES DE INFORMACIÓN
PROGRAMACIÓN ORIENTADA A OBJETOS.
PROYECTO FINAL
TEMA: MUSICA
OBJETIVO.- Implementar un pequeño sistema que permita:
• Ingresar información
• Búsqueda de información
2
3. • Modificar información
• Borrar información
• Almacenar en un archivo de texto.
ALCANCE:
El presente trabajo cuanta con diferentes opciones para el manejo de información de Música
Bailable
Codigo de la cancion.- dato de tipo int, código de la canción que queremos ingresar
Nombre de la canción.- dato de tipo int, nombre de la canción ingresada
Autor de canción.- dato de tipo char, autor de la canción
Ano de Lanzamiento- dato de tipo int, Año de lanzamiento de la canción
Tipo de Canción.- dato de tipo char, Que clase de canción es
Tiempo de duración de la canción.- dato de tipo char, tiempo de duración de la canción
Los métodos de todas las subclases son heredadas de la súper clase Música
Ingresar( );
Modificar( );
Eliminar( );
Ingresar( );
Permite ingresar nuevas canciones del tipo:
Código, Nombre. Autor , Año, Tipo, Duración
Eliminar( );
Permite observar y eliminar las canciones que se han creado, mediante un ID
3
4. SUSTENTACIÓN TEÓRICA.
ECLIPSE
Eclipse es un entorno de desarrollo integrado de código abierto
multiplataforma para desarrollar lo que el proyecto llama
"Aplicaciones de Cliente Enriquecido", opuesto a las aplicaciones
"Cliente-liviano" basadas en navegadores. Esta plataforma,
típicamente ha sido usada para desarrollar entornos de desarrollo
integrados (del inglés IDE), como el IDE de Java llamado Java Development
Toolkit (JDT) y el compilador (ECJ) que se entrega como parte de
Eclipse (y que son usados también para desarrollar el mismo
Eclipse). Sin embargo, también se puede usar para otros tipos de
aplicaciones cliente, como BitTorrent Azureus.
Arquitectura
La base para Eclipse es la Plataforma de cliente enriquecido (del
Inglés Rich Client Platform RCP). Los siguientes componentes
constituyen la plataforma de cliente enriquecido:
• Plataforma principal - inicio de Eclipse, ejecución de plugins
• OSGi - una plataforma para bundling estándar.
• El Standard Widget Toolkit (SWT) - Un widget toolkit portable.
• JFace - manejo de archivos, manejo de texto, editores de texto
• El Workbench de Eclipse - vistas, editores, perspectivas,
asistentes
Los widgets de Eclipse están implementados por un herramienta
de widget para Java llamada SWT, a diferencia de la mayoría de las
aplicaciones Java, que usan las opciones estándar Abstract Window
Toolkit (AWT) o Swing. La interfaz de usuario de Eclipse también tiene
una capa GUI intermedia llamada JFace, la cual simplifica la
construcción de aplicaciones basada en SWT.
4
5. En cuanto a las aplicaciones clientes, eclipse provee al
programador con frameworks muy ricos para el desarrollo de
aplicaciones gráficas, definición y manipulación de modelos de
software, aplicaciones web, etc. Por ejemplo, GEF (Graphic Editing
Framework - Framework para la edición gráfica) es un plugin de
Eclipse para el desarrollo de editores visuales que pueden ir desde
procesadores de texto wysiwyg hasta editores de diagramas UML,
interfaces gráficas para el usuario (GUI), etc. Dado que los editores
realizados con GEF "viven" dentro de Eclipse, además de poder ser
usados conjuntamente con otros plugins, hacen uso de su interfaz
gráfica personalizable y profesional.
Características
La versión actual de Eclipse dispone de las siguientes
características:
• Editor de texto
• Resaltado de sintaxis
• Compilación en tiempo real
• Pruebas unitarias con JUnit
• Control de versiones con CVS
• Integración con Ant
• Asistentes (wizards): para creación de proyectos, clases, tests,
etc.
• Refactorización
Asimismo, a través de "plugins" libremente disponibles es posible
añadir:
• Control de versiones con Subversion.
• Integración con Hibernate.
DIAGRAMA UML
5
6. Lenguaje Unificado de Modelado (UML, por sus siglas en
inglés, Unified Modeling Language) es el lenguaje de
modelado de sistemas de software más conocido y utilizado
en la actualidad; está respaldado por el OMG (Object
Management Group). Es un lenguaje gráfico para visualizar,
especificar, construir y documentar un sistema. UML ofrece
un estándar para describir un "plano" del sistema (modelo),
incluyendo aspectos conceptuales tales como procesos de
negocio y funciones del sistema, y aspectos concretos como
expresiones de lenguajes de programación, esquemas de
bases de datos y componentes reutilizables.
Es importante resaltar que UML es un "lenguaje" para
especificar y no para describir métodos o procesos. Se utiliza
para definir un sistema, para detallar los artefactos en el
sistema y para documentar y construir. En otras palabras, es
el lenguaje en el que está descrito el modelo.
Se puede aplicar en el desarrollo de software entregando
gran variedad de formas para dar soporte a una metodología
de desarrollo de software (tal como el Proceso Unificado
Racional o RUP), pero no especifica en sí mismo qué
metodología o proceso usar.
UML no puede compararse con la programación
estructurada, pues UML significa (Lengua de Modelación
Unificada), no es programación, solo se diagrama la realidad
de una utilización en un requerimiento. Mientras que,
programación estructurada, es una forma de programar
como lo es la orientación a objetos, sin embargo, la
orientación a objetos viene siendo un complemento perfecto
6
7. de UML, pero no por eso se toma UML sólo para lenguajes
orientados a objetos
UML cuenta con varios tipos de diagramas, los cuales
muestran diferentes aspectos de las entidades
representadas.
Modelo de Clases Utilizando Estándar UML.
Un diagrama de clases sirve para visualizar las relaciones
entre las clases que involucran el sistema, las cuales pueden
ser asociativas, de herencia, de uso y de contenido.
Un diagrama de clases esta compuesto por los siguientes
elementos:
• Clase: atributos, métodos y visibilidad.
• Relaciones: Herencia, Composición, Agregación,
Asociación y Uso.
ELEMENTOS.
• Clase.
Es la unidad básica que encapsula toda la información de un
Objeto (un objeto es una instancia de una clase). A través de
ella se puede modelar el entorno en estudio (una Casa, un
Auto, una Cuenta Corriente, etc.).
En UML, una clase es representada por un rectángulo que
posee tres divisiones:
En donde:
o Superior: Contiene el nombre de la Clase.
7
8. o Intermedio: Contiene los atributos (o variables de
instancia) que caracterizan a la Clase (pueden ser
private, protected o public).
o Inferior: Contiene los métodos u operaciones, los
cuales son la forma como interactúa el objeto con
su entorno (dependiendo de la visibilidad: private,
protected o public).
Ejemplo:
Una Cuenta Corriente que posee como característica:
o Balance
Puede realizar las operaciones de:
o Depositar
o Girar
o y Balance
El diseño asociado es:
ATRIBUTOS Y MÉTODOS.
Atributos.
Los atributos o características de una Clase pueden ser de
tres tipos, los que definen el grado de comunicación y
visibilidad de ellos con el entorno, estos son:
• public (+, ): Indica que el atributo será visible tanto
dentro como fuera de la clase, es decir, es accesible
desde todos lados.
• private (-, ): Indica que el atributo sólo será accesible
desde dentro de la clase (sólo sus métodos lo pueden
accesar).
8
9. • protected (#, ): Indica que el atributo no será accesible
desde fuera de la clase, pero si podrá ser accesado por
métodos de la clase además de las subclases que se
deriven (ver herencia).
Métodos.
Los métodos u operaciones de una clase son la forma en
como ésta interactúa con su entorno, éstos pueden tener las
características:
public (+, ): Indica que el método será visible tanto
dentro como fuera de la clase, es decir, es accesible
desde todos lados.
private (-, ): Indica que el método sólo será accesible
desde dentro de la clase (sólo otros métodos de la clase
lo pueden accesar).
protected (#, ): Indica que el método no será accesible
desde fuera de la clase, pero si podrá ser accesado por
métodos de la clase además de métodos de las
subclases que se deriven (ver herencia).
RELACIONES ENTRE CLASES.
Ya definido el concepto de Clase, es necesario entender
como se pueden interrelacionar dos o más clases (cada uno
con características y objetivos diferentes).
Antes es necesario explicar el concepto de cardinalidad de
relaciones: En UML, la cardinalidad de las relaciones indica el
grado y nivel de dependencia, se anotan en cada extremo de
la relación y éstas pueden ser:
• uno o muchos: 1..* (1..n)
• 0 o muchos: 0..* (0..n)
• número fijo: m (m denota el número).
Herencia (Especialización/Generalización):
Indica que una subclase hereda los métodos y atributos
especificados por una Super Clase, por ende la Subclase
además de poseer sus propios métodos y atributos, poseerá
las características y atributos visibles de la Super Clase
(public y protected), ejemplo:
9
10. Agregación:
Para modelar objetos complejos, n bastan los tipos de datos
básicos que proveen los lenguajes: enteros, reales y
secuencias de caracteres. Cuando se requiere componer
objetos que son instancias de clases definidas por el
desarrollador de la aplicación, tenemos dos posibilidades:
Por Valor: Es un tipo de relación estática, en donde el
tiempo de vida del objeto incluido esta condicionado por
el tiempo de vida del que lo incluye. Este tipo de relación
es comúnmente llamada Composición (el Objeto base se
construye a partir del objeto incluido, es decir, es "parte/
todo").
Por Referencia: Es un tipo de relación dinámica, en donde el
tiempo de vida del objeto incluido es independiente del
que lo incluye. Este tipo de relación es comúnmente
llamada Agregación (el objeto base utiliza al incluido para
su funcionamiento).
Asociación:
La relación entre clases conocida como Asociación, permite
asociar objetos que colaboran entre si. Cabe destacar que no
es una relación fuerte, es decir, el tiempo de vida de un
objeto no depende del otro.
Ejemplo:
Un cliente puede tener asociadas muchas Ordenes de
Compra, en cambio una orden de compra solo puede tener
asociado un cliente.
Dependencia o Instanciación (uso):
Representa un tipo de relación muy particular, en la que una
clase es instanciada (su instanciación es dependiente de otro
objeto/clase). Se denota por una flecha punteada.
El uso más particular de este tipo de relación es para denotar
la dependencia que tiene una clase de otra, como por
10
11. ejemplo una aplicación grafica que instancia una ventana (la
creación del Objeto Ventana esta condicionado a la
instanciación proveniente desde el objeto Aplicación):
Cabe destacar que el objeto creado (en este caso la Ventana
gráfica) no se almacena dentro del objeto que lo crea (en
este caso la Aplicación).
CASOS PARTICULARES.
Clase Abstracta.
Una clase abstracta se denota con el nombre de la clase y de
los métodos con letra "itálica". Esto indica que la clase
definida no puede ser instanciada pues posee métodos
abstractos (aún no han sido definidos, es decir, sin
implementación). La única forma de utilizarla es definiendo
subclases, que implementan los métodos abstractos
definidos.
Clase parametrizada.
Una clase parametrizada se denota con un sub-cuadro en el
extremo superior de la clase, en donde se especifican los
11
12. parámetros que deben ser pasados a la clase para que esta
pueda ser instanciada. El ejemplo más típico es el caso de un
Diccionario en donde una llave o palabra tiene asociado un
significado, pero en este caso las llaves y elementos pueden
ser genéricos. La genericidad puede venir dada de un
Template (como en el caso de C++) o bien de alguna
estructura predefinida (especialización a través de clases).
En el ejemplo no se especificaron los atributos del
Diccionario, pues ellos dependerán exclusivamente de la
implementación que se le quiera dar.
ALGUNOS CONCEPTOS UTILIZADOS EN EL PROGRAMA
Después de haber visto los conceptos más importantes sobre
la clase objeto, debemos incursionarnos en los formatos que
son indispensables en la elaboración de clases y subclases
para manejar los diferentes métodos aplicados en la
realización de este trabajo.
A continuación vamos a puntualizar los más destacados e
importantes dentro del código fuente, pues las demás
atributos se lo toma como aprendidos en clase y
sobrentendidos en el transcurso del curso.
• This y Super
Al acceder a variables de instancia de una clase, la palabra
clave this hace referencia a los miembros de la propia clase.
Volviendo al ejemplo de MiClase, se puede añadir otro
constructor de la forma siguiente:
public class MiClase {
int i;
public MiClase() {
i = 10;
}
// Este constructor establece el valor de i
public MiClase( int valor ) {
this.i = valor; // i = valor
}
public void Suma_a_i( int j ) {
i = i + j;
}
}
Aquí this.i se refiere al entero i en la clase MiClase .
Si se necesita llamar al método padre dentro de una clase
que ha reemplazado ese método, se puede hacer referencia
al método padre con la palabra clave super :
12
13. import MiClase;
public class MiNuevaClase extends MiClase {
public void Suma_a_i( int j ) {
i = i + ( j/2 );
super.Suma_a_i( j );
}
}
• Herencia
La Herencia es el mecanismo por el que se crean nuevos
objetos definidos en términos de objetos ya existentes. Por
ejemplo, si se tiene la clase Ave, se puede crear la subclase
Pato, que es una especialización de Ave.
class Pato extends Ave {
int numero_de_patas;
}
La palabra clave extends se usa para generar una subclase
(especialización) de un objeto. Una Pato es una subclase de
Ave. Cualquier cosa que contenga la definición de Ave será
copiada a la clase Pato, además, en Pato se pueden definir
sus propios métodos y variables de instancia. Se dice que
Pato deriva o hereda de Ave.
Además, se pueden sustituir los métodos proporcionados por
la clase base. Utilizando nuestro anterior ejemplo de MiClase,
aquí hay un ejemplo de una clase derivada sustituyendo a la
función Suma_a_i() :
import MiClase;
public class MiNuevaClase extends MiClase {
public void Suma_a_i( int j ) {
i = i + ( j/2 );
}
}
Ahora cuando se crea una instancia de MiNuevaClase, el
valor de i también se inicializa a 10, pero la llamada al método
Suma_a_i() produce un resultado diferente:
MiNuevaClase mnc;
mnc = new MiNuevaClase();
mnc.Suma_a_i( 10 );
• Interfaces
Los métodos abstractos son útiles cuando se quiere que
cada implementación de la clase parezca y funcione igual,
13
14. pero necesita que se cree una nueva clase para utilizar los
métodos abstractos.
Los interfaces proporcionan un mecanismo para abstraer los
métodos a un nivel superior.
Un interface contiene una colección de métodos que se
implementan en otro lugar. Los métodos de una clase son
public , static y final .
La principal diferencia entre interface y abstract es que un interface
proporciona un mecanismo de encapsulación de los
protocolos de los métodos sin forzar al usuario a utilizar la
herencia.
Por ejemplo:
public interface VideoClip {
// comienza la reproduccion del video
void play();
// reproduce el clip en un bucle
void bucle();
// detiene la reproduccion
void stop();
}
Las clases que quieran utilizar el interface VideoClip utilizarán
la palabra implements y proporcionarán el código necesario para
implementar los métodos que se han definido para el
interface:
class MiClase implements VideoClip {
void play() {
<código>
}
void bucle() {
<código>
}
void stop() {
<código>
}
Al utilizar implements para el interface es como si se hiciese
una acción de copiar-y-pegar del código del interface, con lo
cual no se hereda nada, solamente se pueden usar los
métodos.
• Variables y Métodos Estáticos
En un momento determinado se puede querer crear una
clase en la que el valor de una variable de instancia sea el
mismo (y de hecho sea la misma variable) para todos los
objetos instanciados a partir de esa clase. Es decir, que
14
15. exista una única copia de la variable de instancia. Se usará
para ello la palabra clave static .
class Documento extends Pagina {
static int version = 10;
}
El valor de la variable version será el mismo para cualquier
objeto instanciado de la clase Documento . Siempre que un
objeto instanciado de Documento cambie la variable version ,
ésta cambiará para todos los objetos.
De la misma forma se puede declarar un método como
estático, lo que evita que el método pueda acceder a las
variables de instancia no estáticas:
class Documento extends Pagina {
static int version = 10;
int numero_de_capitulos;
static void annade_un_capitulo() {
numero_de_capitulos++; // esto no funciona
}
static void modifica_version( int i ) {
version++; // esto si funciona
}
}
La modificación de la variable numero_de_capitulos no
funciona porque se está violando una de las reglas de acceso
al intentar acceder desde un método estático a una variable
no estática.
Todas las clases que se derivan, cuando se declaran
estáticas, comparten la misma página de variables; es decir,
todos los objetos que se generen comparten la misma zona
de memoria. Las funciones estáticas se usan para acceder
solamente a variables estáticas.
class UnaClase {
int var;
UnaClase()
{
var = 5;
}
UnaFuncion()
{
var += 5;
}
}
En el código anterior, si se llama a la función UnaFuncion a
través de un puntero a función, no se podría acceder a var ,
porque al utilizar un puntero a función no se pasa
implícitamente el puntero al propio objeto ( this ). Sin embargo,
15
16. sí se podría acceder a var si fuese estática, porque siempre
estaría en la misma posición de memoria para todos los
objetos que se creasen de UnaClase.
• La clase StringBuffer
Java posee gran capacidad para el manejo de cadenas
dentro de sus clases String y StringBuffer . Un objeto String
representa una cadena alfanumérica de un valor constante
que no puede ser cambiada después de haber sido creada.
Un objeto StringBuffer representa una cadena cuyo tamaño
puede variar.
La clase StringBuffer dispone de muchos métodos para
modificar el contenido de los objetos StringBuffer. Si el
contenido de una cadena va a ser modificado en un
programa, habrá que sacrificar el uso de objetos String en
beneficio de StringBuffer, que aunque consumen más
recursos del sistema, permiten ese tipo de manipulaciones.
Al estar la mayoría de las características de los StringBuffers
basadas en su tamaño variable, se necesita un nuevo método
de creación:
StringBuffer();
StringBuffer( int len );
StringBuffer( String str );
Se puede crear un StringBuffer vacío de cualquier longitud y
también se puede utilizar un String como punto de partida
para un StringBuffer.
StringBuffer Dos = new StringBuffer( 20 );
StringBuffer Uno = new StringBuffer( "Hola Mundo" );
Cambio de Tamaño
El cambio de tamaño de un StringBuffer necesita varias
funciones específicas para manipular el tamaño de las
cadenas:
int length();
char charAt( int index );
void getChars( int srcBegin,int srcEnd,char dst[],int dstBegin );
String toString();
void setLength( int newlength );
void setCharAt( int index,char ch );
int capacity();
void ensureCapacity( int minimum );
void copyWhenShared();
16
17. Obervar que una de las funciones devuelve una cadena
constante normal de tipo String. Este objeto se puede usar
con cualquier función String, como por ejemplo, en las
funciones de comparación.
Modificación del Contenido
Para cambiar el contenido de un StringBuffer, se pueden
utilizar dos métodos: append() e insert() .
En el ejemplo CadAppend.java , vemos el uso de estos dos
métodos:
class CadAppend {
public static void main( String args[] ) {
StringBuffer str = new StringBuffer( "Hola" );
str.append( " Mundo" );
System.out.println( str );
}
}
Operadores de Concatenación
Hay que recordar que los operadores " + " y " += " también se
pueden aplicar a cadenas. Ambos realizan una concatenación
y están implementados con objetos StringBuffer.
Por ejemplo, la sentencia:
String s = "¿Qué" + " tal ?";
es interpretada por el compilador como:
String s =
new StringBuffer().append( "¿Qué" ).append( " tal ?" ).toString();
y se marcaría el StringBuffer para borrarlo ya que el
contenido pasa al objeto String.
• La clase Integer
Cada tipo numérico tiene su propia clase de objetos. Así el
tipo int tiene el objeto Integer . De la misma forma que con la
clase Character , se han codificado muchas funciones útiles
dentro de los métodos de la clase Integer .
Declaraciones
17
18. La primera sentencia creará una variable int y la segunda un
objeto Integer:
Integer.MIN_VALUE;
Integer.MAX_VALUE;
Valores de Integer
Integer.MIN_VALUE;
Integer.MAX_VALUE;
Métodos de Integer
String Integer.toString( int i,int base );
String Integer.toString( int i );
int I.parseInt( String s,int base );
int I.parseInt( String s );
Integer Integer.valueOf( String s,int base );
Integer Integer.valueOf( String s );
int I.intValue();
long I.longValue();
float I.floatValue();
double I.doubleValue();
String I.toString();
int I.hashCode();
boolean I.equals( Object obj );
Los valores boolean también tienen su tipo asociado Boolean ,
aunque en este caso hay menos métodos implementados que
para el resto de las clases numéricas.
Declaraciones
La primera sentencia creará una variable boolean y la
segunda un objeto Boolean:
boolean b;
Boolean B;
Valores de Boolean
Boolean.TRUE;
Boolean.FALSE;
Métodos de Boolean
boolean B.booleanValue();
String B.toString();
boolean B.equals( Object obj );
• Excepciones
try-catch-throw
18
19. try {
sentencias;
} catch( Exception ) {
sentencias;
}
Java implementa excepciones para facilitar la construcción de
código robusto. Cuando ocurre un error en un programa, el
código que encuentra el error lanza una excepción, que se
puede capturar y recuperarse de ella. Java proporciona
muchas excepciones predefinidas.
El manejo y control de excepciones es tan importante en Java
que debe ser tratado en un capítulo aparte, aunque sirva este
punto como mención previa de su existencia.
• Control General del Flujo
break
break [etiqueta];
La sentencia break puede utilizarse en una sentencia switch o
en un bucle. Cuando se encuentra en una sentencia switch,
break hace que el control del flujo del programa pase a la
siguiente sentencia que se encuentre fuera del entorno del
switch. Si se encuentra en un bucle, hace que el flujo de
ejecución del programa deje el ámbito del bucle y pase a la
siguiente sentencia que venga a continuación del bucle.
Java incorpora la posibilidad de etiquetar la sentencia break,
de forma que el control pasa a sentencias que no se
encuentran inmediatamente después de la sentencia switch o
del bucle, es decir, saltará a la sentencia en donde se
encuentre situada la etiqueta. La sintaxis de una sentencia
etiquetada es la siguiente:
etiqueta: sentencia;
continue
continue [etiqueta];
La sentencia continue no se puede utilizar en una sentencia
switch, sino solamente en bucles. Cuando se encuentra esta
sentencia en el discurrir normal de un programa Java, la
iteración en que se encuentre el bucle finaliza y se inicia la
siguiente.
19
20. Java permite el uso de etiquetas en la sentencia continue, de
forma que el funcionamiento normal se ve alterado y el salto
en la ejecución del flujo del programa se realizará a la
sentencia en la que se encuentra colocada la etiqueta.
Por ejemplo, al encontrarse con bucles anidados, se pueden
utilizar etiquetas para poder salir de ellos:
uno: for( ) {
dos: for( ) {
continue; // seguiría en el bucle interno
continue uno; // seguiría en el bucle principal
break uno; // se saldría del bucle principal
}
}
Hay autores que sugieren que el uso de sentencias break y
continue etiquetadas proporciona una alternativa al infame goto
(que C++ todavía soporta, pero Java no, aunque reserva la
palabra). Quizá se así, pero el entorno de uso de las
sentencias etiquetadas break y continue es mucho más
restrictivo que un goto. Concretamente, parece que un break o
continue con etiqueta, compila con éxito solamente si la
sentencia en que se encuentra colocada la etiqueta es una
sentencia a la que se pueda llegar con un break o continue
normal.
return
return expresión;
La sentencia return se utiliza para terminar un método o
función y opcionalmente devolver un valor al método de
llamada.
En el código de una función siempre hay que ser
consecuentes con la declaración que se haya hecho de ella.
Por ejemplo, si se declara una función para que devuelva un
entero, es imprescindible colocar un return final para salir de
esa función, independientemente de que haya otros en medio
del código que también provoquen la salida de la función. En
caso de no hacerlo se generará un Warning, y el código Java no
se puede compilar con Warnings.
int func() {
if( a == 0 )
return 1;
return 0; // es imprescindible porque se retorna un entero
}
20
21. Si el valor a retornar es void, se puede omitir ese valor de
retorno, con lo que la sintaxis se queda en un sencillo:
return;
y se usaría simplemente para finalizar el método o función en
que se encuentra, y devolver el control al método o función
de llamada.
Esta sentencia se puede utilizar para mostrar uno de los
problemas para los que Java está destinado a corregir. En C+
+ se permite que los valores de retorno de una función o
método puedan ser por valor o por referencia. Cuando se
devuelve un valor por referencia, o un puntero, en C++, hay
que asegurarse de que el objeto referenciado continúe
existiendo a la terminación del método. Por ejemplo, si se
devuelve un puntero o una referencia a una variable local de
la función, pueden presentarse problemas, porque esa
variable deja de existir tan pronto como finaliza la función.
El compilador Borland C++ utilizado por el autor para realizar
pruebas, no permite que se devuelva una referencia a una
variable local, pero sí que permite devolver un puntero a esa
variable. El siguiente programa, java409.cpp, es muy simple e
ilustra esto. Crea un array en la función principal para
modificar la memoria y luego utiliza el puntero devuelto para
presentar el contenido de la memoria a la que apunta ese
puntero. El programa presenta en pantalla porquería, porque
después de que termine la función, el puntero apunta a una
dirección de memoria que ya no es válida para el programa.
Sin embargo, compilando la aplicación con GNU C++ y
corriendo sobre Linux, el valor que se presenta sí es el correcto.
#include <iostream.h>
int *test() { // Declara la variable local a la función
int variableLocal = 6; // Guarda su dirección en un puntero
int *puntero = &variableLocal;
// Devuelve el puntero a la variable local
return puntero;
}
void main() {
// Recoge el puntero devuelto por la función de test
int *punteroMain = test();
// Rellena con cosas la memoria
int memArray[5] = { 10,11,12,13,14 };
// Presenta en pantalla el contenido de la zona a que apunta el
// puntero
cout << "El contenido de la memoria es " << *punteroMain;
}
21
22. Aparentemente en Java, solamente se puede retornar por
valor. En el caso de tipos básicos, se devuelve una copia del
item retornado. Si no se quiere devolver una copia, siempre
está la posibilidad de utilizar las versiones objeto de los tipos
básicos.
• Manejo de excepciones
Vamos a mostrar como se utilizan las excepciones,
reconvirtiendo nuestro applet de saludo a partir de la versión
iterativa de HolaIte.java :
import java.awt.*;
import java.applet.Applet;
public class HolaIte extends Applet {
private int i = 0;
private String Saludos[] = {
"Hola Mundo!",
"HOLA Mundo!",
"HOLA MUNDO!!"
};
public void paint( Graphics g ) {
g.drawString( Saludos[i],25,25 );
i++;
}
}
Normalmente, un programa termina con un mensaje de error
cuando se lanza una excepción. Sin embargo, Java tiene
mecanismos para excepciones que permiten ver qué
excepción se ha producido e intentar recuperarse de ella.
Vamos a reescribir el método paint() de nuestra versión
iterativa del saludo:
La palabra clave finally define un bloque de código que se
quiere que sea ejecutado siempre, de acuerdo a si se capturó
la excepción o no. En el ejemplo anterior, la salida en la
consola, con i=4 sería:
• Capturar Excepciones
Las excepciones lanzadas por un método que pueda hacerlo
deben recoger en bloque try/catch o try/finally .
try
22
23. Es el bloque de código donde se prevé que se genere una
excepción. Es como si dijésemos "intenta estas sentencias y
mira a ver si se produce una excepción". El bloque try tiene
que ir seguido, al menos, por una cláusula catch o una
cláusula finally
catch
Es el código que se ejecuta cuando se produce la excepción.
Es como si dijésemos "controlo cualquier excepción que
coincida con mi argumento". En este bloque tendremos que
asegurarnos de colocar código que no genere excepciones.
Se pueden colocar sentencias catch sucesivas, cada una
controlando una excepción diferente. No debería intentarse
capturar todas las excepciones con una sola cláusula, como
esta:
catch( Excepcion e ) { ...
Esto representaría un uso demasiado general, podrían llegar
muchas más excepciones de las esperadas. En este caso es
mejor dejar que la excepción se propague hacia arriba y dar
un mensaje de error al usuario.
Se pueden controlar grupos de excepciones, es decir, que se
pueden controlar, a través del argumento, excepciones
semejantes
que aparezcan en el programa. Si hay alguno que coincida,
se ejecuta el bloque. El operador instanceof se utiliza para
identificar exactamente cual ha sido la identidad de la
excepción.
finally
Es el bloque de código que se ejecuta siempre, haya o no
excepción. Hay una cierta controversia entre su utilidad, pero,
por ejemplo, podría servir para hacer un log o un seguimiento
de lo que está pasando, porque como se ejecuta siempre
puede dejarnos grabado si se producen excepciones y nos
hemos recuperado de ellas o no.
• Excepciones Predefinidas
Las excepciones predefinidas y su jerarquía de clases es la
que se muestra en la figura:
23
24. Los nombres de las excepciones indican la condición de error
que representan. Las siguientes son las excepciones
predefinidas más frecuentes que se pueden encontrar:
ArithmeticException
Las excepciones aritméticas son típicamente el resultado de
una división por 0:
int i = 12 / 0;
NullPointerException
Se produce cuando se intenta acceder a una variable o
método antes de ser definido:
class Hola extends Applet {
Image img;
paint( Graphics g ) {
g.drawImage( img,25,25,this );
}
}
24
25. IncompatibleClassChangeException
El intento de cambiar una clase afectada por referencias en
otros objetos, específicamente cuando esos objetos todavía
no han sido recompilados.
ClassCastException
El intento de convertir un objeto a otra clase que no es válida.
y = (Prueba)x; // donde
x no es de tipo Prueba
NegativeArraySizeException
Puede ocurrir si hay un error aritmético al intentar cambiar el
tamaño de un array.
OutOfMemoryException
¡No debería producirse nunca! El intento de crear un objeto
con el operador new ha fallado por falta de memoria. Y siempre
tendría que haber memoria suficiente porque el garbage collector
se encarga de proporcionarla al ir liberando objetos que no se
usan y devolviendo memoria al sistema.
NoClassDefFoundException
Se referenció una clase que el sistema es incapaz de
encontrar.
ArrayIndexOutOfBoundsException
Es la excepción que más frecuentemente se produce. Se
genera al intentar acceder a un elemento de un array más allá
de los límites definidos inicialmente para ese array.
UnsatisfiedLinkException
Se hizo el intento de acceder a un método nativo que no
existe. Aquí no existe un método a.kk
class A {
native void kk();
}
25
26. InternalException
Este error se reserva para eventos que no deberían ocurrir.
Por definición, el usuario nunca debería ver este error y esta
excepción no debería lanzarse.
• Ficheros
Todos los lenguajes de programación tienen alguna forma de
interactuar con los sistemas de ficheros locales; Java no es
una excepción.
Cuando se desarrollan applets para utilizar en red, hay que
tener en cuenta que la entrada/salida directa a fichero es una
violación de seguridad de acceso. Muchos usuarios
configurarán sus navegadores para permitir el acceso al
sistema de ficheros, pero otros no.
Antes de realizar acciones sobre un fichero, necesitamos un
poco de información sobre ese fichero. La clase File
proporciona muchas utilidades relacionadas con ficheros y
con la obtención de información básica sobre esos ficheros.
Creación de un objeto File
Para crear un objeto File nuevo, se puede utilizar cualquiera
de los tres constructores siguientes:
File miFichero;
miFichero = new File( "/etc/kk" );
o
miFichero = new File( "/etc","kk" );
o
File miDirectorio = new File( "/etc" );
miFichero = new File( miDirectorio,"kk" );
El constructor utilizado depende a menudo de otros objetos
File necesarios para el acceso. Por ejemplo, si sólo se utiliza
un fichero en la aplicación, el primer constructor es el mejor.
Si en cambio, se utilizan muchos ficheros desde un mismo
directorio, el segundo o tercer constructor serán más
cómodos. Y si el directorio o el fichero es una variable, el
segundo constructor será el más útil.
• Ficheros de Acceso Aleatorio
A menudo, no se desea leer un fichero de principio a fin; sino
acceder al fichero como una base de datos, donde se salta
26
27. de un registro a otro; cada uno en diferentes partes del
fichero. Java proporciona una clase RandomAccessFile para este
tipo de entrada/salida.
Creación de un Fichero de Acceso Aleatorio
Hay dos posibilidades para abrir un fichero de acceso
aleatorio:
Con el nombre del fichero:
miRAFile = new RandomAccessFile( String nombre,String modo );
Con un objeto File:
miRAFile = new RandomAccessFile( File fichero,String modo );
El argumento modo determina si se tiene acceso de sólo
lectura ( r ) o de lectura/escritura ( r/w ). Por ejemplo, se
puede abrir un fichero de una base de datos para
actualización:
RandomAccessFile miRAFile;
miRAFile = new RandomAccessFile( "/tmp/kk.dbf","rw" );
Acceso a la Información
Los objetos RandomAccessFile esperan información de
lectura/escritura de la misma manera que los objetos
DataInput/DataOutput. Se tiene acceso a todas las
operaciones read() y write() de las clases DataInputStream y
DataOutputStream.
También se tienen muchos métodos para moverse dentro de
un fichero:
long getFilePointer();
Devuelve la posición actual del puntero del fichero
void seek( long pos );
Coloca el puntero del fichero en una posición determinada. La
posición se da como un desplazamiento en bytes desde el
comienzo del fichero. La posición 0 marca el comienzo de ese
fichero.
long length();
27
28. Devuelve la longitud del fichero. La posición length() marca el
final de ese fichero.
Actualización de Información
Se pueden utilizar ficheros de acceso aleatorio para añadir
información a ficheros existentes:
Listas
Hay varias implementaciones de List, siendo ArrayList la que
debería ser la elección por defecto, en caso de no tener que
utilizar las características que proporcionan las demás
implementaciones.
ArrayList
Es una Lista volcada en un Array. Se debe utilizar en lugar de
Vector como almacenamiento de objetos de propósito general.
Permite un acceso aleatorio muy rápido a los elementos, pero
realiza con bastante lentitud las operaciones de insertado y
borrado de elementos en medio de la Lista. Se puede utilizar
un ListIterator para moverse hacia atrás y hacia delante en la
Lista, pero no para insertar y eliminar elementos.
Sets
Set tiene exactamente el mismo interfaz que Collection, y no hay
ninguna funcionalidad extra, como en el caso de las Listas. Un
Set es exactamente una Colección, pero tiene utilizada en un
entorno determinado, que es ideal para el uso de la herencia
o el polimorfismo. Un Set sólo permite que exista una instancia
de cada objeto.
A continuación se muestran las diferentes implementaciones
de Set, debiendo utilizarse HashSet en general, a no ser que se
necesiten las características proporcionadas por alguna de
las otras implementaciones.
Set (interfaz)
Cada elemento que se añada a un Set debe ser único, ya que
el otro caso no se añadirá porque el Set no permite almacenar
elementos duplicados. Los elementos incorporados al
28
29. Conjunto deben tener definido el método equals(), en aras de
establecer comparaciones para eliminar duplicados. Set tiene
el mismo interfaz que Collection, y no garantiza el orden en que
se encuentren almacenados los objetos que contenga.
ARCHIVOS DE TEXTO
Si se desea procesar datos de un archivo existente, se debe:
1. Abrir el archivo
2. Leer o introducir los datos en las variables, un elemento
a la vez
3. Cerrar el archivo cuando se termine de trabajar con él
Para transferir algunos datos de ciertas variables a un
archivo, se debe:
1. Abrir el archivo
2. Extraer o escribir los elementos en la secuencia
requerida
3. Cerrar el archivo cuando se termine de trabajar con él
Al leer un archivo, todo lo que puede hacerse es leer el
siguiente elemento. Si, por ejemplo, quisiéramos examinar el
último elemento, tendríamos que codificar un ciclo para leer
cada uno de los elementos en turno, hasta llegar al elemento
requerido. Para muchas tareas, es conveniente visualizar un
archivo como una serie de líneas de texto, cada una
compuesta por un número de caracteres y que termina con el
carácter de fin de línea. Un beneficio de esta forma de trabajo
es la facilidad de transferir archivos entre aplicaciones. Así se
podría crear un archivo ejecutando un programa en Java y
después cargarlo en un procesador de palabras, editor de
texto o correo electrónico.
Las clases de flujo están organizadas de la siguiente forma:
Reader
BufferedReader
InputStreamReader
FileReader
29
30. Writer
PrintWriter
FileWriter
Para procesar archivos se utilizan las clases BufferedReader
y PrintWriter para leer y escribir líneas de texto, y para la
entrada que no provenga de archivos (desde el teclado y
páginas Web) también se utiliza InputSreamReader.
Los programas que utilizan archivos deben contener la
instrucción: import java.io.*;
"Búfer" significa que, el software lee un gran trozo de datos
del dispositivo de almacenamiento externo y lo guarda en la
RAM, de tal forma que invocaciones sucesivas de los
métodos que necesitan leer una pequeña cantidad de datos
del dispositivo de almacenamiento de archivos puedan
obtener rápidamente los datos de la RAM. Por lo tanto, un
búfer actúa como un amortiguador entre el dispositivo de
almacenamiento y el programa.
La clase File
Esta clase ofrece la capacidad de manipular archivos y
directorios en general.
No se utiliza para tener acceso a los datos dentro de los
archivos.
Se necesita utilizar la instrucción: import java.io.*;
La mayoría de los sistemas operativos ofrecen una estructura
jerárquica con una ruta para avanzar a través de la misma,
cuya forma es:
d:estructuraDeDatosJavaArchivosInventario.java
Ésta es una ruta estilo Windows que utiliza '' como
separador. En un sistema UNIX se utiliza como separador '/'.
Si usted necesita escribir software para manipular rutas y que
funcione en cualquier sistema puede averiguar cúal es el
separador de archivos haciendo referencia a la constante de
la cadena File.separator.
La ruta mostrada anteriormente es absoluta, empieza desde
la parte superior del directorio y lo lleva hasta el archivo. No
30
31. obstante, a veces esto es irrelevante: sólo necesitamos tratar
con rutas que sean relativas al directorio actual. Por ejemplo,
si nos encontramos en el directorio Java, entonces la ruta de
Inventario.java sería ArchivosInventario.java.
Inicialmente debemos construir una instancia de la clase File
proporcionando una cadena. Una vez creada se puede
utilizar. Considere la siguiente instrucción:
File archivo = new File
("c:estructuraDeDatosJavaArchivosInventario.java");
Como el caracter de escape '' es casualmente el mismo que
el separador de archivos en Window, se necesita decir que
es simplemente un caracter normal de la cadena en vez de
tener un significado especial, por lo que hay que anteponerle
un caracter de escape. Así, representa a .
FUNCIONAMIENTO DEL PROGRAMA
El programa principal utiliza todas las características
mencionadas en el artículo presente, por lo que el modo de
funcionamiento tiene basadas las características antes
mencionadas con la interfaz gráfica que permite una
interacción con el usuario por medio de ventanas, las mismas
que despliegan la información, solicitando al usuario las
diferentes opciones que presenta, en cada cuadro de diálogo.
Por ejemplo, para el menú principal se tiene:
31
32. Si se escoge la primera opción, aparecerá otro menú
mostrando lo siguiente:
En este existen las diferentes opciones de un menú general,
por lo que si se selecciona por ejemplo la opción 2:
32
33. aparecerá en orden los menús solicitando la información
requerida:
código que identificará a la
canción
Para el código existe un parámetro que debe cumplirse, de lo
contrario no se procederá continuar con el programa y con
esto no se almacenará lo que se ingrese; el parámetro es de
M[x][n] [n] [n]
Donde: x hace referencia a la inicial del tipo de canción
inicial, ejemplo: Bailable B; ClásicaC, etc., y
n es un dígito entero; por lo que se necesitan 3
dígitos
33
34. el nombre de la
canción
el autor de la
canción
año de la canción
En este caso se debe cumplir que esté entre los años 1900
hasta el 2010.
Este cuadro es
para el género más específico de la canción.
34
35. Por último
está el tiempo de duración que en este caso está estimado
por un valor double.
Al terminar podremos escoger la opción de guardado, que es
la única manera de almacenar los datos ingresados,
escogiendo la opción 5:
y como demostración que se van almacenando una tras otra
las canciones, se puede abrir el documento de texto que es
utilizado para este propósito.
Como se puede observar se encuentra almacenado al final
del archivo, con lo que concluye la explicación de
almacenamiento.
35
36. Para búsqueda es un proceso de lectura que pide parámetros
y para borrado igualmente, por lo que hay que tener atención
a qué es lo que se quiere buscar o eliminar.
CONCLUSIONES Y RECOMENDACIONES:
• Eclipse es un entorno de desarrollo integrado de código abierto
multiplataforma para desarrollar lo que el proyecto llama
"Aplicaciones de Cliente Enriquecido", opuesto a las
aplicaciones "Cliente-liviano" basadas en navegadores.
• Al realizar este programa, encontramos que existe
diferentes tipos para expresar las variables que
vayamos a utilizar y a la vez debemos utilizar.
• Nos pudimos dar cuenta que el resultado del proyecto
debería darnos con un interfaz agradable con el usuario,
para que se diferencien los objetivos señalados
• La visualización de todo el trabajo se basa
específicamente en tres niveles de objetos, para poder
identificar aun más los comandos utilizados para este
propósito.
• Algunas especificaciones varían de acuerdo a lo
solicitado por el usuario, como son por ejemplo en las
clases y tipos de datos a utilizarse para la
implementación del mismo.
• Para obtener el diagrama UML hay que tener en claro
los conceptos de clases, objetos, atributos y métodos.
• Hay que tener en cuenta la forma de elaborar los
diagramas UML que quisiéramos utilizar.
• Los diagramas que utilizamos son elaborado mediante
herencias y por eso no encontramos los atributos y
métodos.
• En nuestro programa utilizamos el manejo de
excepciones y archivos.
• Una excepción es un evento que ocurre durante la
ejecución de un programa y detiene el flujo normal de la
secuencia de instrucciones de ese programa; en otras
palabras, una excepción es una condición anormal que
surge en una secuencia de código durante su ejecución.
36
37. • Cuando queremos preservar la información es necesario
guardarlo en un almacenamiento de tipo no volátil: este
es el almacenamiento secundario
• .
• El SDK de Eclipse incluye las herramientas de desarrollo
de Java, ofreciendo un IDE con un compilador de Java
interno y un modelo completo de los archivos fuente de
Java. Esto permite técnicas avanzadas de
refactorización y análisis de código.
BIBLIOGRAFIA:
Diagrama UML
• http://es.wikipedia.org/wiki/Lenguaje_Unificado_de_Modelad
o
• http://tvdi.det.uvigo.es/~avilas/UML/node37.html
Eclipse
• http://es.wikipedia.org/wiki/Eclipse
Herencias
• http://www.webtaller.com/manual-java/herencia.php
• http://www.itapizaco.edu.mx/paginas/JavaTut/froufe/parte4/c
ap4-7.html#Cap4_7_4
• http://www.webtaller.com/manual-java/this-super.php
• http://www.itapizaco.edu.mx/paginas/JavaTut/froufe/parte4/c
ap4-7.html#Cap4_7_4
Interfaces
• http://www.webtaller.com/manual-java/this-super.php
• http://www.webtaller.com/manual-java/interfaces.php
• http://www.itapizaco.edu.mx/paginas/JavaTut/froufe/parte4/c
ap4-7.html#Cap4_7_4
Variables y Métodos estáticos
37