0% encontró este documento útil (0 votos)
12 vistas12 páginas

Arrays Orientados A Objetos

Derechos de autor
© © All Rights Reserved
Nos tomamos en serio los derechos de los contenidos. Si sospechas que se trata de tu contenido, reclámalo aquí.
Formatos disponibles
Descarga como DOCX, PDF, TXT o lee en línea desde Scribd
0% encontró este documento útil (0 votos)
12 vistas12 páginas

Arrays Orientados A Objetos

Derechos de autor
© © All Rights Reserved
Nos tomamos en serio los derechos de los contenidos. Si sospechas que se trata de tu contenido, reclámalo aquí.
Formatos disponibles
Descarga como DOCX, PDF, TXT o lee en línea desde Scribd
Está en la página 1/ 12

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.

Recuerde que la mayoría de los elementos de la clase Keyboard tienen especificado el


modificador de acceso public y también el modificador static. La clase Keyboard se
implementa a partir de los métodos next---() de la clase Scanner.

La mayoría de los métodos de la clase Keyboard incorporan captura de excepciones, por


lo tanto si sucede un problema al ingresar un valor, se captura un tipo de excepción, se da
un mensaje de error y se permite intentar de nuevo.

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í

public class App {

public static void main(String[] args) {


menu();
}

private static void menu() {



}

private static void inicializar() {



}

private static void salir() {



}

static int leerOpcion() {



}

Esta App debe mostrar un menú de opciones como el de la imagen siguiente:

3. Implemente la clase Matrix como se muestra enseguida:

package edu.prog2.model;

public class Matrix {

private int[][] data;


private int rows;
private int columns;

public Matrix(int rows, int columns) {


this.rows = rows;
this.columns = columns;
data = new int[rows][columns];
}

public int getRows() {


return rows;
}

public int getColumns() {


return columns;
}

public void setValue(int i, int j, int value) {


data[i][j] = value;
}

public void display() {


for (int i = 0; i < rows; i++) {
for (int j = 0; j < columns; j++) {
System.out.printf("%5d", data[i][j]);
}
System.out.println();
}
}

Esta clase utiliza los siguientes nuevos conceptos de la programación orientada a objetos:

a. Los atributos, también llamados datos o variables miembro. Estos definen la


información que un objeto posee o conoce de sí mismo. Una clase puede tener
cualquier número de atributos o no tener ninguno. Se declaran con un identificador,
un tipo y preferiblemente tienen asociado un modificador que define su visibilidad.
La clase Matrix tiene los siguientes tres atributos:
private int[][] data;
private int filas;
private int columnas;

b. La clase también define un constructor, un “método” o “función” especial que se


utiliza para inicializar un objeto cuando se crea. Los constructores tienen el mismo
nombre que su clase y no tienen un tipo de devolución explícito dado que de
manera implícita retornan una instancia de la clase que los define. Ejemplo:
public Matrix(int filas, int columnas) {
this.filas = filas;
this.columnas = columnas;
data = new int[filas][columnas];
}
Note el uso de la palabra reservada this para referirse a dos de los atributos de la
clase y poder así diferenciarlos de los parámetros que recibe el constructor. La
palabra reservada this también se puede utilizar para llamar a constructores o
métodos dentro de la clase que los define.

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;
}

public int getColumns() {


return columns;
}

d. Proceda como en el paso anterior para definir un accesor para el atributo data de
esta clase.

e. La clase también define un mutador. Los métodos mutadores se utilizan para


asignar o establecer un valor a un atributo. En este caso se ha definido un mutador
que permite establecer un valor en una celda determinada de la matriz data:
public void setValue(int i, int j, int value) {
data[i][j] = value;
}

En los pasos siguientes se indica la forma de utilizar la clase Matrix.

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.

También se hubiera podido hacer sólo la definición de la referencia:


static Matrix matrix;

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);

5. Agregue para el caso 1 de la App un llamado al método display() de la clase Matrix:

case 1:
matrix.display();
break;

Pruebe el caso 1, deberá obtener una matriz nula de 4 x 5.

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.

6. Agregue el siguiente método a la clase App:

private static void asignarValores() {


String mensaje = new String("Ingrese el número de filas: ");
int filas = Keyboard.readInt(mensaje);

int columnas = Keyboard.readInt("Ingrese el número de columnas: ");


matrix = new Matrix(filas, columnas);

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);

System.out.println("\nMatriz luego de asignarle valores:\n");


matrix.display();
}

A continuación se comentan algunos detalles interesantes de esta implementación:

● La instrucción String mensaje = new String("Ingrese el número de filas:


"); indica que los valores a una variable de tipo String se pueden asignar con
alguno de la decena o más de constructores que proporciona la clase String,
lógicamente en este caso hubiera sido más cómodo escribir:
String mensaje = "Ingrese el número de filas: ";

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:

int filas = Keyboard.readInt("Ingrese el número de filas: ");

● La siguiente instrucción redefine el tamaño de la matriz que originalmente es de


4x5 por el tamaño indicado por el usuario:

matrix = new Matrix(filas, columnas);


● La siguiente instrucción usa dos accesores de la clase para obtener y mostrar el
tamaño de la matriz:

System.out.printf(
"%nMatriz inicial de %d filas por %d columnas:%n%n",
matrix.getRows(), matrix.getColumns()
);

● Las siguientes instrucciones usan un mutador de la clase para establecer el valor


20 en la posición [2, 1] y el valor 10 en la posición [3, 0]:
matrix.setValue(2, 1, 20);
matrix.setValue(3, 0, 10);

● También se vuelve a utilizar la instrucción matrix.display() para mostrar los


valores de la matriz antes y después de asignarle valores.

7. Modifique el caso 1 para llamar al método del paso anterior y probar el comportamiento.

8. La primera instrucción de un constructor puede ser el llamado a un constructor de su


misma clase. Teniendo en cuenta esto, agregue otro constructor a la clase Matrix que
permita crear matrices cuadradas. Este nuevo constructor sólo recibe el parámetro size y
llama al constructor existente de la siguiente forma:

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:

public int getRandom(int min, int max) {


if (max < min) {
int temp = min;
min = max;
max = temp;
}

Random random = new Random();


return random.nextInt(max - min) + min;
}

10. Implemente el siguiente método en la clase Matrix, de tal manera que rellene la matriz data
con valores aleatorios:

public void randomize(int min, int max) { … }

11. Agregue el siguiente método a la clase App y use el caso 2 para probarlo:

private static void crearMatrizCuadrada() {


int tamanio = Keyboard.readInt("Tamaño de la matriz cuadrada: ");
Matrix m2 = new Matrix(tamanio);

int inicio = Keyboard.readInt("Valor mínimo para llenar celdas: ");


int fin = Keyboard.readInt("Valor máximo para llenar celdas: ");
m2.randomize(inicio, fin);

m2.display();
}

Deberá obtener un comportamiento como el de la imagen siguiente. Si no es así revise los


tres pasos anteriores para corregir lo que haya quedado mal implementado:

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.

13. Agregue un accesor para el atributo data.

14. En la clase App cree el siguiente método y llámelo en el caso 3:

private static void pruebaReferencia() {


matrix.randomize(10, 100);
matrix.display();
System.out.println();

int[][] m = matrix.getData();
for (int j = 0; j < m[1].length; j++) {
m[1][j] = m[1][j] + 100;
}
matrix.display();
}

15. Observe el comportamiento de la opción anterior y luego documente el método


getData() de la clase Matrix con el comentario que crea correcto de los dos siguientes:

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:

public int[][] copyData() {…}

17. En la clase App cree el siguiente método y llámelo en el caso 4:

private static void pruebaCopia() {


matrix.randomize(10, 100);
matrix.display();
System.out.println();

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().

18. Agregue un nuevo constructor a la clase Matrix:

public Matrix(int[][] m) { … }

Este constructor asigna el tamaño de la matriz m a los atributos respectivos de la matriz


data y también copia en data los elementos de la matriz recibida como argumento.

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) {…}

La implementación de este constructor sólo requiere dos líneas de código.

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:

● Llene a matrix con números aleatorios entre 100 y 999.


● Muestre a matrix.
● En una variable local de tipo Matrix cree un instancia de Matrix utilizando el
constructor del paso 18. Dicho constructor recibirá como argumento la matriz
traspuesta.
● Muestre el número de filas y columnas de la matriz traspuesta.
● Muestre la matriz traspuesta.
Si procede correctamente el resultado será similar a lo siguiente:
23. Implemente de forma óptima en la clase Matrix, el método public Matrix identity
(int size). Este método recibe el tamaño de una matriz y como su nombre lo indica,
retorna una instancia de Matrix que contiene la matriz identidad correspondiente.

24. El método matrizIdentidad() implementado en la clase App y usado en el caso 6 para


probar el punto anterior, permitir ingresar por teclado el tamaño de la matriz.

25. El método public Matrix product(Matrix m) multiplica la matriz contenida en


this.data con la matriz de la instancia recibida como argumento. Este método retorna una
instancia de Matrix que contiene en data el producto resultante.

Este método lanza la siguiente excepción si el argumento m es null:


throw new NullPointerException("Se esperaba una matriz");

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:

a. Llene de valores aleatorios la matriz de la instancia matrix definida a nivel de la


clase App y despliegue su contenido.

b. Solicite que se ingrese el número de filas y columnas utilizando Keyboard.readInt().

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.

e. Despliegue el contenido de las matrices del punto c y del punto d.

Si implementa correctamente se genera una traza de errores como la que se muestra


enseguida, cuando las dimensiones de las matrices no hace posible obtener el producto:
Cuando el número de columnas de la matriz del punto a es igual al número de filas de la
matriz del punto c, se debe obtener correctamente el producto de las dos matrices:

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");

28. Implemente en la App, para el caso 7, la función sumarMatrices() de manera similar a


productoMatrices() pero teniendo en cuenta que no es necesario ingresar el número de
filas y columnas puesto que las matrices son iguales y la clase Matrix proporciona los
accesores para conocer el número de filas y columnas.

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:

public static Matrix lowerTriangular(int size) { … }

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;

public class Utils {

public static final String RESET = "\u001B[0m";


public static final String BLACK = "\u001B[30m";
public static final String RED = "\u001B[31m";
public static final String GREEN = "\u001B[32m";
public static final String YELLOW = "\u001B[33m";
public static final String BLUE = "\u001B[34m";
public static final String PURPLE = "\u001B[35m";
public static final String CYAN = "\u001B[36m";
public static final String WHITE = "\u001B[37m";
public static final String PATH = "./data/";

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.

También podría gustarte