Arrays Orientados A Objetos
Arrays Orientados A Objetos
Estos talleres tienen como fin continuar con el repaso de algunos temas de programación 1, entre
ellos: funciones y formaciones unidimensionales y bidimensionales (arrays). Mientras se repasan
dichos temas, se irán introduciendo otros nuevos relacionados con el uso de clases. Tenga
especial cuidado con el uso de mayúsculas y minúsculas propuesto para definir identificadores.
1. Empiece por crear un proyecto Maven. Para el caso del ejemplo se ha llamado arrays.
La carpeta helpers se utilizará como un package que podrá llegar a contener varios
elementos. Esta carpeta sólo contendrá las clases Utils y Keyboard. Los métodos de esta
última se utilizarán siempre que requiera ingresar datos.
En resumen, las clases Utils y Keyboard incorporan algunos conceptos relacionados con la
programación orientada a objetos sobre los cuales puede conocer detalles ingresando a
los enlaces que se incluyen a continuación:
● Concepto de package: los paquetes son el mecanismo que usa Java para facilitar
la modularidad del código. Un paquete puede contener una o más clases e incluso
otros elementos como interfaces y enumeraciones, de las cuales se hablará más
adelante.
● Concepto de clase: una clase es la descripción de un conjunto de objetos similares,
es decir es un clasificador que define características y comportamientos de objetos.
● Constantes en Java: como su palabra lo dice es un dato que no cambia.
● Modificadores de acceso: formas de indicar la visibilidad de los miembros de una
clase.
● Modificador static: una palabra que se usa para definir miembros de clase, aquellos
que pertenecen a una clase, en lugar de pertenecer a un objeto en particular. Por
ejemplo todas las funciones que proporciona la clase Math de Java.
● Captura de excepciones: las excepciones son una estrategia para intentar
conseguir que si un código fuente no se ejecuta de la forma esperada se pueda
controlar la situación e indicar cómo ha de responderse ante el hecho.
2. Implemente la clase App como la de cualquier proyecto básico orientado a objetos que
requiera un menú de opciones:
package edu.prog2;
import java.util.Locale;
import edu.prog2.helpers.Keyboard;
import edu.prog2.helpers.Utils; // 👀 esta clase se documenta aquí
package edu.prog2.model;
Esta clase utiliza los siguientes nuevos conceptos de la programación orientada a objetos:
c. Puesto que los atributos de la clase son privados, no son accesibles por fuera de
ésta y fue necesario definir dos métodos accesores para permitir obtener
información de los atributos filas y columnas. Estos métodos se caracterizan por su
nomenclatura getNameAttribute().
public int getRows() {
return rows;
}
d. Proceda como en el paso anterior para definir un accesor para el atributo data de
esta clase.
4. Al inicio del bloque de la clase App, justo antes del método main() defina el siguiente
atributo matrix:
static Matrix matrix = new Matrix(4, 5);
El editor mostrará un error y le pedirá que importe la clase Matrix del paquete model.
Sin embargo en el método main() o en cualquier otro método de la clase se tendría que
utilizar el constructor de la clase para crear la instancia y así poderla utilizar:
matrix = new Matrix(4, 5);
Note el uso del operador new en la asignación para crear la nueva instancia mediante el
llamado al constructor public Matrix(int filas, int columnas) { … }.
De la misma manera se hubieran podido crear y utilizar tantas instancias de la clase Matrix
como fueran necesarias. Ejemplo:
static Matrix m2 = new Matrix(10, 6);
static Matrix m3 = new Matrix(7, 12);
case 1:
matrix.display();
break;
Note además que en el taller anterior cuando se necesita llamar a un método de la clase
Keyboard se hacía de la forma Clase.método(), y que es claro que la instrucción
matrix.display(), utiliza la forma instancia.método().
Se dice entonces que los métodos de la clase Keyboard son miembros de clase o
estáticos y que los de la clase Matrix son miembros de instancia. Note que los miembros
de clase se definen con el modificador static y que los miembros de instancia no.
System.out.printf(
"%nMatriz inicial de %d filas por %d columnas:%n%n",
matrix.getRows(), matrix.getColumns()
);
matrix.display();
// se asignan valores sólo en las celdas [2, 1] y [3, 0]:
matrix.setValue(2, 1, 20);
matrix.setValue(3, 0, 10);
Incluso lo más óptimo sería haber reducido las dos primeras instrucciones a una,
pero se quería enfatizar que String es una clase y no un tipo de dato primitivo:
System.out.printf(
"%nMatriz inicial de %d filas por %d columnas:%n%n",
matrix.getRows(), matrix.getColumns()
);
7. Modifique el caso 1 para llamar al método del paso anterior y probar el comportamiento.
this([param1[, … paramN]]);
9. Agregue a la clase Matrix el siguiente método que genera y retorna un entero aleatorio en
el rango indicado por los parámetros:
10. Implemente el siguiente método en la clase Matrix, de tal manera que rellene la matriz data
con valores aleatorios:
11. Agregue el siguiente método a la clase App y use el caso 2 para probarlo:
m2.display();
}
12. Implemente en Matrix el accesor getValue(...) de tal manera que como argumentos se
reciba un número de fila, luego un número de columna y se retorne el valor de la celda
correspondiente.
int[][] m = matrix.getData();
for (int j = 0; j < m[1].length; j++) {
m[1][j] = m[1][j] + 100;
}
matrix.display();
}
Comentario 1:
/**
* Retorna una copia de los datos de la matriz data
* @return La matriz de datos definida como atributo de clase
*/
Comentario 2:
/**
* Devuelve una referencia a los datos de la matriz data
* @return la referencia a la matriz de datos
*/
Tenga en cuenta que la documentación de los métodos se coloca inmediatamente encima
de su definición con un formato exactamente igual al que se muestra en los comentarios.
16. Como su nombre lo indica, el método copyData() retorna una copia de la matriz data, no
una referencia a dicha matriz. Para que esto sea posible se crea una matriz local al método
del mismo tamaño de la matriz data, se transfiere a ella los elementos de la matriz data y
se retorna la matriz local. Implemente el siguiente método en la clase Matrix, según las
especificaciones dadas:
int[][] m = matrix.copyData();
for (int j = 0; j < m[1].length; j++) {
m[1][j] = m[1][j] + 100;
}
matrix.display();
}
Documente este método indicando por qué los comportamientos son distintos cuando se
utiliza getData() y copyData().
public Matrix(int[][] m) { … }
19. Agregue un nuevo constructor a la clase Matrix. Este nuevo constructor copia la data del
objeto m en el data de this y lo mejor de todo, sólo requiere una línea de código si aplica lo
implementado en el punto 16:
public Matrix(Matrix m) { … }
20. Agregue un último constructor que permita crear instancias de Matrix con una data de un
número determinado de filas y columnas. En las celdas de la matriz data quedarán
asignados números aleatorios en un rango determinado por los parámetros min y max.
public Matrix(int rows, int cols, int min, int max) {…}
21. Cree en la clase Matrix el método int[][] transposedMatrix() para que retorne la matriz
traspuesta.
22. Para el caso 5 de la App cree la función traspuesta() según estas indicaciones:
También lanza la siguiente excepción si dados los tamaños de las matrices no se pueden
multiplicar:
throw new ArrayIndexOutOfBoundsException("El número de columnas de la
matriz A
no es igual al número de filas de la matriz B");
26. Implemente en la App, para el caso 8, la función productoMatrices() teniendo en cuenta las
siguientes indicaciones:
c. Cree una instancia local de Matrix del tamaño ingresado y con valores aleatorios.
Uno de los constructores le permitirá hacer esto en una sola línea de código.
d. En otra instancia local de Matrix asigne el producto que se obtenga de la matriz del
punto a por la matriz del punto c.
27. Proceda de forma similar a como se indica en los dos puntos anteriores para que el
método Matrix add(Matrix m) retorne una instancia de Matrix que contenga la suma
de la matriz contenida en this y la matriz de la instancia recibida como argumento.
El método debe generar el siguiente error cuando las matrices no sean de igual tamaño:
throw new ArrayIndexOutOfBoundsException("Las matrices no son de igual
tamaño");
29. Agregue a la clase Matrix un método que permita devolver una instancia de Matrix cuyo
atributo data contenga una matriz triangular superior. Tenga en cuenta que al crear una
matriz, según el constructor que se use, ésta queda con todos los elementos en cero, por
lo tanto luego de crearla sólo hay que llenar el triángulo superior de celdas con números
aleatorios entre 1 y 100. La plantilla del método a implementar es el siguiente:
public static Matrix upperTriangular(int size) { … }
30. Compruebe en caso 9 de la App que el siguiente método permite mostrar una matriz
triangular superior de cualquier tamaño:
private static void matrizTriangularSuperior() {
int tamanio = Keyboard.readInt("Ingrese el tamaño de la matriz: ");
Matrix.upperTriangular(tamanio).display();
}
Note que aunque el método upperTriangular(), retorna una instancia de Matrix, ésta
no se está asignando a variable alguna. Esto es válido cuando la instancia no se requiere
más adelante.
31. Agregue a la clase Matrix un método que permita devolver una instancia de Matrix cuyo
atributo data contenga una matriz triangular inferior. La plantilla del método a implementar
es el siguiente:
32. Para el caso 10 de la App implemente un método similar al del punto 30.
33. Haga que el constructor Matrix(int rows, int cols) lance una excepción cuando
el número de filas o columnas recibidos como argumentos sea inferior a 2.
34. Observe que tanto la clase Keyboard como la clase Utils sólo definen miembros de clase
(estáticos) mientras que la clase Matrix define tanto estáticos como de instancia. Según
esto, de la clase Keyboard y de la clase Utils no se van a crear instancias, por lo tanto es
válido definir los constructores private Keyboard() {} y private Utils() {} en
dichas clases para evitar que erróneamente se puedan crear instancias de estas clases.
35. Al terminar la implementación de la clase Matrix es necesario darle un poco de orden, así
que tenga en cuenta que primero deben ir definidos todos los constructores, luego los
accesores y los mutadores y por último el resto de métodos.
También se valora que el código esté documentado de acuerdo a los estándares dados y
que haya dado formato al código fuente.
La clase Util
Esta es la versión resumida y resumida de la clase Utils que se referencia en el punto 2:
package edu.prog2.helpers;
private Utils() {
// ...
}
Posiblemente su proyecto ni siquiera requiera dicha clase pero es importante que por su cuenta
elabore el proyecto básico orientado a objetos, ya que más adelante necesitará conceptos y
utilidades que se encuentran en este taller.