Bienvenido a este nuevo módulo, vamos ahora a construir una colección de discos que será un catálogo. El objetivo principal es programar las actividades del manejo de un catálogo de discos, de los que se pueden solicitar transmisiones. Daremos una breve descripción, se ofrece un catálogo de discos que ofrece transmisiones. Los servicios que debe dar ese catálogo, por ejemplo, son: agregar un disco al catálogo, iniciar el catálogo con una colección de discos ya construidos, mostrar el catálogo de discos, iniciar una transmisión de un disco seleccionado y registrarla, mostrar los discos que están en transmisión, para una transmisión activa de un disco dado, terminar la transmisión y liberarla, registrar el fin de una transmisión en el histórico de transmisiones para ese disco, mostrar el histórico de transmisiones para cada disco, mostrar un menú con las opciones disponibles. Haremos nuevamente nuestra tarjeta de responsabilidades. La clase se va a llamar Catálogo con mayúsculas, y los datos o atributos que va a tener el catálogo es un identificador llamado catálogo, "c" con minúscula. Es una colección de discos y, cada disco, es un objeto. Para el catálogo, debemos tener cuántos discos tiene el catálogo discos y, para cada disco, necesitamos una colección de fechas que nos dará cuando está iniciando cada transmisión. Para llevar el registro, tendrás un histórico que es para cada disco, pareja de fechas de cuándo se inició y finalizó la transmisión, también, cuántos registros tenemos en el histórico. De las responsabilidades que queremos que tenga el catálogo, está primero "addCatalogo" que agrega un disco al catálogo si es que hay lugar, dice si lo agregó o no, por lo tanto, la salida es "booleana" y la entrada es un disco. "DaTransmision", registra la transmisión del disco elegido a una cierta hora, avisa si pudo o no, como entrada recibe la posición del disco y, como salida, me dice si lo pudo registrar o no. "TerminaTransmisión", le damos la posición del disco en el catálogo y la consola por la que nos va a comunicar, pregunta de este disco, ¿cuál es la transmisión a eliminar? y transcribe el inicio y final al histórico, avisa si pudo o no, por lo tanto, regresa una "booleana". "MuestraCatalogo" te dará una cadena con la lista de discos, como entrada recibe un encabezado, y muestra la lista de discos dados de alta. "MuestraActivos", regresa la cadena con la lista de discos en transmisión, recibe un encabezado y da una lista de los discos activos. "MuestraActivas", le doy la posición del disco, regresa una cadena con la lista de transmisiones activas. "MuestraHistorico", da la lista de transmisiones iniciadas y finalizadas para ese disco, le doy como entrada la posición del disco y regresa una cadena con el histórico del disco. "MuestraHistorias", muestra la lista de transmisiones iniciadas y finalizadas para cada uno de los discos, no le doy nada como entrada y, como salida, me da una cadena con el histórico de todos los discos. Finalmente, tenemos "conectaCatalogo", que es el que interactúa con el usuario y el catálogo, no recibe ninguna entrada y no entrega ninguna salida. Tenemos los Constructores, vamos a darle un constructor sin parámetros que construye un catálogo con el máximo número de posiciones, y todos los arreglos asociados, un constructor que recibe el número de discos, y construye la colección para acomodar ese número de discos, un constructor que recibe dos parámetros, el máximo número de discos que puede tener, y una colección inicial de discos, como salida me da un catálogo. Vas a empezar a programar ese proyecto, para facilitar la lectura en DrJava, le pedirás que enumere las líneas del archivo, y así, poder referirse a ellas directamente. En la pestaña "edit", le darás clic en preferencias, y ahí en "Display Options", y te vas a la selección de "Show All Line Numbers", le damos en "aplicar" y al final en "OK". Vemos que, aún, cuando el archivo está vacío, aparecen los números de líneas. Regresamos al proyecto de catálogo de discos, tienes que hacer unas modificaciones a la clase Disco. La firma que tienes de "daTransmision" en la interfaz Servicios Disco es la siguiente. Vamos a cargar el archivo de Servicios Disco, vemos que el método "daTransmision" no tiene parámetros porque él mismo calcula el calendario. Abriremos el archivo "Disco". Ahora, necesitamos tener otro método al que le podamos pasar como entrada la fecha y hora, por lo tanto, para evitar problemas con la interfaz de Disco, no vamos a modificar este método, sino lo que haremos es hacer uno nuevo. Cómo sigues cumpliendo con la interfaz, todos los encabezados están contemplados y no tenemos problema en agregar métodos públicos que no aparecen en la interfaz. La nueva clase Disco seguirá funcionando bien con el viejo usuario, simplemente, no hará uso de este método. Copiamos el método "daTransmision" junto con su comentario y lo pegamos a continuación del primero. Lo que tenemos que hacer es actualizar el comentario, porque este método debe tener un parámetro de tipo "Gregorian Calendar" y viene con fecha y hora en la que se está pidiendo la transmisión. Tenemos que corregir, también, el encabezado, recibe un Gregorian Calendar que se llamará "miCal". Debemos eliminar la línea donde se creaba "miCal", vamos a compilar y vemos que compila bien, cerramos ambos archivos. La clase correspondiente a cada uno de los discos ya la tienes, empiezas con la clase que va a representar al catálogo de discos llamada Catálogo. El catálogo de discos debe tener una colección de discos y colecciones asociadas a cada disco, para llevar la administración de este catálogo. A las colecciones de datos, en general, se les llama estructuras de datos. Podríamos tener un ejemplo, una bolsa de canicas, estante de discos,o una pila de platos, debes elegir qué tipo de estructura de datos requieres para representar a las colecciones que están en el catálogo de discos. Por lo pronto, necesitamos una colección de discos y de fechas que son de "GregorianCalendar", usarás arreglos para representar las colecciones que necesitas. Los arreglos, los podemos ver como una sucesión de posiciones que contienen un objeto u otro arreglo, son la estructura de datos más común en programación. Un arreglo es un objeto, pero por ser tan comunes, nos permiten usar operadores específicos, lo que les da una notación particular concisa para manejarlos. Los arreglos organizan a datos del mismo tipo, lo que los hace estructuras de datos homogéneas. Los organiza como listas, formándolos uno detrás del otro, lo que los hace estructuras lineales. Puedes obtener un dato específico dando su ubicación dentro del arreglo, lo que los hace estructuras de acceso directo. Una vez construido el arreglo no se puede disminuir o aumentar su capacidad, lo que los hace estructuras estáticas. Cada elemento de un arreglo puede ser, a su vez, un arreglo, y así, sucesivamente, por lo que decimos que pueden tener una o más dimensiones, el número de dimensiones queda definido por el número de parejas de corchetes en la declaración. Si el arreglo es de una sola dimensión, un único renglón queda declarado como sigue. Primero, el tipo del arreglo, luego, una pareja de corchetes y el identificador. El tipo se refiere al que van a tener todos los elementos del arreglo que pueden ser primitivos como "int", "boolean", "char", una clase como Disco o GregorianCalendar, o también puede ser una interfaz. El identificador se nombra con las reglas de Java, es un identificador común, por lo tanto, va en minúsculas. Podemos pensar en los arreglos de una dimensión como se muestra en la figura, el número en rojo indica la ubicación de un elemento en el renglón, lo ponemos entre corchetes. Aquí, en el ejemplo, es "cuatro". Si el arreglo es de dos dimensiones, uno o más renglones, una o más columnas, queda declarado con la siguiente sintaxis. El tipo es como en el caso anterior, el tipo que va a tener cada uno de los elementos de la estructura, se usan dos pares de corchetes para indicar dos dimensiones y se piensa como si fuera una tabla o matriz, pero todas las columnas son del mismo tipo y se distinguen entre sí por la posición en la que están. La abstracción es una tabla de este tipo, donde tenemos que empiezan las columnas y renglones en "cero", la posición "dos, cuatro" es en el renglón número dos, o sea, el tercer renglón y la columna cuatro, o sea, la quinta columna. Aquí, tenemos la posición en el primer renglón que tiene el índice "cero", y la segunda columna que tiene el índice "uno". Si el arreglo es de tres dimensiones debe haber tres parejas de corchetes, concebimos un arreglo de tres dimensiones como "block" de páginas cuadriculadas, una detrás de la otra, y cada página es una tabla de renglones y columnas. Cada dimensión se enumera desde "cero", la abstracción es de este tipo, como una página seguida de la otra. Por ejemplo, aquí tendremos la tercera página que tiene el número dos en el primer renglón, que es el número "cero", y en la cuarta columna que es la posición tres. Este otro tiene la primera página, que es la posición "cero", en el tercer renglón, que es la posición "dos", y en la quinta columna que es la posición "cuatro". Vamos a ver la sintaxis para la declaración de un arreglo, primero, vienen los accesos y modificadores, si es que estamos declarando campos o atributos, pero esto no existe en las declaraciones locales. El tipo corresponde al de cada uno de los elementos individuales del arreglo, el número de dimensiones son las parejas de corchetes sucesivas y el identificador. Siguen las reglas de JAVA, se pueden declarar más de un identificador del mismo tipo separados entre sí por comas, el tamaño de cada dimensión se da hasta que se haga la definición del arreglo. Veamos unos ejemplos, en este caso, tenemos un arreglo de tres dimensiones de enteros, es una declaración local, no tiene modificadores y se llama "juegos Ganados", es una tabla de equipos. Aquí tenemos un arreglo de una dimensión, es privado, por lo tanto, es un atributo, se llama catálogo con minúsculas y es un catálogo de discos. A continuación, tenemos en lugar de lo que teníamos en disco, que era una cadena, tenemos un arreglo de cadenas que se llama "NDIAS", es una constante de la clase. Por último, el arreglo de "GregorianCalendar", que es el histórico, también va a ser un atributo del objeto, y tomamos la clase GregorianCalendar, declaramos un arreglo de dos dimensiones, el tamaño de cada dimensión se dará en la construcción. Puedes construir arreglos haciendo una asignación al identificador del arreglo. Esto se puede hacer en la declaración, lo cual, es obligatorio si se trata de una constante de clase. Tienes dos formas de hacerlo a continuación de un operador de asignación. Para arreglos "static" y "final" tienes que listar todos los componentes de cada dimensión entre llaves y separando los componentes por comas, tienen que ser del mismo tipo todos los componentes. Si, nada más, vas a dar el tamaño de cada dimensión, puedes hacerlo con "new", el tipo que declaraste en el arreglo, y luego, una sucesión de expresiones enteras dentro de cada pareja de corchetes. Después de "new", "tipo", excepto por el primero, se puede ir construyendo dimensión por dimensión de izquierda a derecha, dejando el resto de corchetes vacíos. Por ejemplo, si hiciéramos un arreglo para los días, empezamos con una llave, tendríamos el lugar "cero" con una cadena vacía, el lugar "uno" con domingo y, esta vez, ya no necesitamos completar con blancos, porque los vamos a localizar directamente en el arreglo. Es un arreglo de una dimensión, se llama "NDIAS". Cada cadena ocupa un lugar en el arreglo, pones una cadena vacía en el lugar "cero" para poder usar, directamente, el número de día entre "uno" y "siete". El contenido del arreglo se da entre llaves, con los elementos separados entre sí por comas. El número de elementos de una dimensión de un arreglo se obtiene con el atributo público "length" que está en todo arreglo. Noten que no es una función, sino un atributo, por lo tanto, no lleva paréntesis. "NDIAS.lenght" vale "ocho". Siempre que se tenga constantes simbólicas de la clase "static / final" se deben inicializar de esta manera, pues no pueden esperar a la ejecución. Para un arreglo de dos o más dimensiones, encierras entre llaves cada dimensión. Por ejemplo, el arreglo que construimos de "juegos Ganados", podemos iniciar en el renglón "cero" colocando, exclusivamente, "ceros", en el renglón "uno", en la columna cero, ponemos un "cero", luego, "tres" coma "cero" coma "cuatro". Nota que están entre llaves cada uno de los renglones, el tercer renglón también ponemos "cero" en la columna cero, y así, sucesivamente. Es un arreglo de dos dimensiones que se llama "juegos Ganados", no es un arreglo de constantes como en el caso anterior, sino con valores iniciales, tiene cuatro elementos que son arreglos. En la primera dimensión, son los renglones del arreglo, está todo entre un par de llaves y tienes una matriz de cuatro renglones por cuatro columnas, no tienen que ser el mismo número de renglones y columnas. En esta inicialización, por ejemplo, el primer renglón tiene cuatro "ceros" y cada renglón tiene en la columna cero, un "cero". Este tipo de inicialización, únicamente, la puedes hacer en el momento de la construcción del objeto o en la declaración. Por ejemplo si deseas un arreglo de objetos disco, puedes declararlo así. Tienes un arreglo de una dimensión cuyos elementos son referencias a objetos de la clase Disco, quieres que tenga "MAX_DISCOS" elementos numerados del "cero" a "MAX_DISCOS" menos "uno". "MAX_DISCOS" debería estar declarada como constante de la clase en la que está esta declaración o la del tipo del arreglo. Todos los elementos tienen en este momento "null", una referencia nula como valor. El tamaño puede cambiar si vuelves a usar "new" con el mismo identificador, pero perderías el contenido que tengas en ese momento. También, podías haber usado esta construcción en los constructores, o cualquier método. Si quieres hacer la construcción de arreglos con contenido, se puede usar la inicialización con llaves si este elemento se lista inmediatamente después de la construcción con "new". Por ejemplo, podemos hacer "juegos Ganados" igual a "new" de "int", y en el caso de un arreglo, se puede poner entre las llaves invocación. Vamos a ver la construcción de arreglos con contenido, ya vimos si se pone a continuación de la declaración, pero también, se puede poner, inmediatamente, a continuación de "new", entonces, no tendría por qué estar en la declaración. En el caso de un arreglo de objetos se pueden poner entre las llaves invocaciones a los constructores de los objetos. Por ejemplo; podríamos definir el catálogo usando "new" con "Disco", que es de una sola dimensión y podríamos poner ahí, cuatro elementos para el catálogo. El problema con llenar el contenido del arreglo al construirlo, es que el número de elementos queda fijado con el número de objetos entre las llaves. Por ejemplo, en el catálogo de la construcción anterior, únicamente, va a contar con cuatro posiciones y no se podrán agregar más discos al catálogo, se puede subsanar este problema listando el valor por omisión, "cero" para números, "null" para objetos y "falso" para "booleanos", tantas veces como queramos que tenga el arreglo como tamaño. En el caso de nuestro catálogo, le agregamos 10 valores "null", esto le daría al arreglo 14 posiciones, diez de ellas con referencias nulas. Como con cualquier objeto en cualquier elemento, incluso una declaración, puedes construir un arreglo que no tenga su contenido definido. Haces una asignación al identificador del arreglo, si el arreglo es de una dimensión, dices cuántos elementos tiene el arreglo con la siguiente sintaxis. Le das al identificador la palabra "new", luego, el tipo y, después, escribes entre una pareja de corchetes una expresión entera que entregue un entero. Para esta expresión puedes invocar funciones, hacer aritmética o cualquier cosa que entregue un entero. Esta expresión dice el tamaño del arreglo con las posiciones o índices empezando en "cero", el índice mayor que tiene el arreglo es la expresión entera que diste, menos "uno". Si "tipo" es numérico, el arreglo se llena de ceros, si es "booleano" se llena de valores "false" y, si es de clase o interfaz, se llena de referencias "null". Los arreglos, como a cualquier objeto, Java los construye en el Heap, que es el espacio de la memoria de la computadora reservada para ellos. Un arreglo de dos dimensiones es un arreglo de arreglos. Puedes, primero, definir cuántos elementos va a tener el primer arreglo, lo que hace que se construya una estructura como la que sigue. Nos vemos en el siguiente video, no te lo puedes perder.