[ Foro de Java ]

Duda sobre la creación de objetos de tipo matricial

27-Mar-2014 19:08
Angel Bravo
4 Respuestas

Dispongo que una clase principal que crea la matriz y llama a los métodos de la clase secundaria llamada "matriz":


class Matricial {
   public static void main(String[] args) {
   Matriz matrizA;    //declaración del objeto matrizA de la clase matriz.
   matrizA = new Matriz();    //Instanciación del objeto MatrizA de la clase matriz.
   matrizA.leerMatriz();
   System.out.println("Matriz A: ");
   matrizA.imprimirMatriz();
   }
}


Esta es la clase secundaria "matriz" , en otro archivo, encargada de leer y "dibujar" la matriz en pantalla:


import java.util.Scanner;

class Matriz {
   byte num_valores;
   int[][] matrizB;    // <- declaración del objeto matrizB.
   byte num_filas, num_col;
   Scanner datosMatriz;
 
   void leerMatriz(/*¿MatrizA como argumento?*/) {
      datosMatriz = new Scanner(System.in);
      System.out.print("Número de filas: ");
      num_filas = datosMatriz.nextByte(); 
      System.out.print("Número de columnas: ");
      num_col = datosMatriz.nextByte();
      matrizB = new int[num_col][num_filas]; // <- instanciación del objeto matrizB.
      for (int c = 0; c < num_filas; c++) {
         for (int f = 0; f < matrizB.length; f++) { // <- matrizB[f].length NO porque...
            System.out.print("Introducir valor " + (f + 1) + " ");
            matrizB[f][c] = datosMatriz.nextInt();
         }
      }
}

   void imprimirMatriz() {
      for (int c = 0; c < num_filas; c++) {
         System.out.print("( ");
         for (int f = 0; f < matrizB.length; f++) {
            System.out.print(matrizB[f][c] + " ");
         }
         System.out.print(")");
         System.out.println(" ");
      }
   }
}


Me pierdo demasiado con esto de la POO, mis preguntas, son:

-) ¿La matrizA y La matrizB son objetos distintos y por tanto direcciones de memoria diferentes?
-)¿Es necesaria la creación de esta última o se puede obviar su declaración e instanciación  haciendo que los métodos de la clase "matriz" llamen a la matrizA? ¿O es la matrizA la que habría que quitar?
-) ¿Debería hacer de la clase "matriz" una clase con cada posible cálculo dentro de ella (determinantes, inversas, traspuestas, etc) o debería hacerla abstracta y jugar con la herencia?.
-) ¿Por qué matrizB[f].length no funciona pero matrizB.length sí pese a que el compilador no me da error?.

Espero su respuesta profesor, un saludo.


28-Mar-2014 22:58
Nacho Cabanes (+83)

En ese fuente concreto:

a) MatrizA es un objeto de tipo Matriz, que tiene atributos y métodos, mientras que matrizB es un array bidimensional, uno de los atributos de los objetos de tipo Matriz, y no contiene métodos. Son cosas muy distintas. Es (más o menos) como decir si un coche y un motor son lo mismo.

b) No puedes quitar ninguna de las dos: si quitas "MatrizA", ya no tienes un objeto de la clase Matriz, de modo que no podrías crear métodos que calculen (por ejemplo) el determinante o la inversa de esa matriz; si quitas "matrizB", el objeto no tiene dónde almacenar sus datos. Volviendo a la analogía: si al coche le quitas el motor, no se puede mover, y deja de ser útil, y, de igual modo, si el motor no lo usas para mover algo, se convierte en algo inútil; ambos se complementan.

c) Tú decides. O haces los cálculos en ella si va a ser siempre una matriz 3x3 (por ejemplo), o la creas como clase abstracta, de modo que las clases hijas sean las que implementen los detalles concretos de cada tipo de matriz, tanto en lo que se refiere a tamaño (3x3 o 4x4, por ejemplo) como en comportamiento (hay métodos abreviados para el determinante de una matriz 2x2 o 3x3, que no podrás aplicar en una 4x4).

d) Si declaras "int[][] matrizB;", entonces "matrizB.length" es la cantidad de filas de la matriz, y "matrizB[f].length"podría ser la cantidad de columnas de la matriz, pero ya que has creado los atributos "byte num_filas, num_col;" y que la matriz puede estar sobredimensionada, lo razonable sería usar estos últimos.


29-Mar-2014 00:29
Angel Bravo

Muchas gracias profesor, aunque el apartado "c" no me queda claro.

La idea no es hacer una subclase por cada tamaño que pudiera tener la matriz, sino por ejemplo, hacer una clase abstracta matriz como la del código, sin ningún método más. Y luego una subclase teniendo cada posible cálculo  de una matriz (determinante, inversa, etc) su método en esa subclase, luego otra subclase para cálculos de dos matrices, otra con sólo una columna para cálculos estadísticos unidimensionales, dos columnas para bidimensionales, etc.... ¿o no hay problema en poner todos los métodos dentro de una misma clase "matriz" y que sea la clase principal la que decida cuántas columnas, filas o matrices necesita?. No sé si soy capaz de hacerme entender..


31-Mar-2014 00:08
Nacho Cabanes (+83)

Primero, unas nociones que creo que estás pasando por alto o que no has entendido correctamente:

Una clase es un conjunto de objetos que comparten características (atributos) y comportamientos (métodos) comunes.

Cuando a partir de una "clase padre" (superclase) creas una "clase hija" (subclase), estás haciendo una versión más refinada, más especializada.

Una clase abstracta es una clase de la que no puedes crear objetos, porque faltan detalles que se implementarán en las subclases. El caso típico es una clase "figura geométrica", con métodos como "dibujar" o "calcularArea". Puedes dibujar un rectángulo, y calcular su área, pero no puedes hacerlo para una figura geométrica si no tienes más detalles sobre el tipo de figura del que se trata.

Ahora vamos a lo práctico...

Si la clase base es "matriz", no tiene sentido una subclase "matriz de la que sé calcular el determinante" y otra subclase "matriz para cálculos". Ambas son matrices. Tú decides si quieres que la clase "matriz" sea abstracta porque no vayas a dar detalles de cómo se calcula su determinante (por ejemplo) y vayas a delegarlos en subclases más especializadas, como Matriz2x2, o si prefieres que la clase matriz haga de todo, aunque algún detalle lo refines en clases hijas. Pero en cualquier caso, una subclase tiene una relación "es un", es decir, una "matriz2x2" es una "matriz" (igual que un "rectángulo" es una "figura geométrica"). Si de una subclase no puedes decir eso, entonces has aplicado la herencia de forma incorrecta.


31-Mar-2014 00:23
Angel Bravo

Creo tener claras esas nociones (que reconozco, mi trabajo me ha costado) aunque gracias por la aclaración. No he debido explicarme correctamente. La cuestión es mucho más simple, si interesa o no (por cuestiones de eficiencia, lentitud, etc...) el tener una clase con una gran cantidad de métodos, en este caso para cualquier operación matricial que se ocurra, o si por el contrario es mejor crear una clase abstracta e ir separando esos métodos por medio de subclases, la idea era simplemente esa, perdone si me he liado demasiado al explicarme.






(No se puede continuar esta discusión porque tiene más de dos meses de antigüedad. Si tienes dudas parecidas, abre un nuevo hilo.)