Autor Tema: conflicto entre nombre de clase y clase del api de java  (Leído 6508 veces)

Susana83

  • Sin experiencia
  • *
  • Mensajes: 49
    • Ver Perfil
conflicto entre nombre de clase y clase del api de java
« en: 01 de Octubre 2014, 10:43 »
El ejercicio dice: corrija el siguiente código Java para que no se generen conflictos con la respuesta esperada de acuerdo con el API de Java. Tenga en cuenta cuál sería el resultado esperado y el resultado que está obteniendo y que no se debe eliminar código, sino sólo corregirlo.

Código: [Seleccionar]
class Vector {
  private int val = 1;
 
  public boolean isEmpty() {
    if (val == 1) {   // compares with 1 instead of 0
      return true;
    } else {
      return false;
    }
  }
  // other functionality is same as java.util.Vector
}
 
// import java.util.Vector; omitted
public class VectorUser {
  public static void main(String[] args) {
    Vector v = new Vector();
    if (v.isEmpty()) {
      System.out.println("Vector is empty");
    } else {System.out.println("Vector is NOT empty"); }
  }
}

Pero no obtengo ningún error ¿os sucede lo mismo?
« Última modificación: 02 de Octubre 2014, 11:34 por Alex Rodríguez »

Jorge lopez

  • Sniper
  • Intermedio
  • ***
  • APR2.COM
  • Mensajes: 248
  • @SniperOfElite
    • Ver Perfil
Re:error oculto java
« Respuesta #1 en: 01 de Octubre 2014, 17:00 »
 Hola Susana83!

Te comento lo siguiente: La clase Vector es una clase del api de java, y pertenece al package "util" de java.

Para poder hacer uso de esta clase en una clase propia, como lo es la clase VectorUser en tu ejercicio, hemos de declarar en cabecera de clase la sentencia "import java.util.Vector;" para evitar un error en compilación.

En tu ejercicio podemos observar una linea de comentario que dice :
Citar
// import java.util.Vector; omitted
(esta sentencia fue omitida), ahora bien, porque si se omitió esta sentencia el código compila?

Respuesta:

Tu clase VectorUser tiene a su vez una clase Vector, definida con el objetivo de ser usada por esta clase (VectorUser), cuando dos clases se encuentran en un mismo package, no es necesario incluir la sentencia "import Projecto.package.NombreDeLaClase" (import java.util.Vector), porque donde el compilador java busca esta clase, es en el package actual desde donde esta siendo invocada la clase, de no encontrarla (por pertenecer a otro package diferente), pues se necesita especificar la ruta de la clase mediante una sentencia import.

Si contamos con una clase Vector en el api de java, y esta disponible su uso, para que crear una clase Vector en tu clase VectorUser? No fuera mas lógico importar la clase Vector mediante una sentencia import?

Aquí es donde entra lo que yo llamaría un "error lógico" en tu ejercicio. Cuando creamos clases debemos evitar usar nombres de clases propias del api de java o javax ext.. Esto para evitar posibles conflictos y resultados inesperados. Lo lógico al crear una clase Vector en vez de importarla, es que nuestra intención sea cambiar o modificar algo en esta nueva clase Vector pero con referencia a la clase "original" Vector del package util, y eso es justamente lo que esta generando un error de lógica, o resultado inesperado en este ejercicio.

Si consultas el método isEmpty (esta vacío) de la ruta java.util.Vector; encontraras el siguiente detalle:
Citar
retorna verdadero si y sólo si este vector no tiene componentes, es decir, su tamaño es cero; false en caso contrario.

En tu clase Vector tenemos una variable int val = 1, que se usa para mediante un condicional if, comparar el tamaño del vector, osea si esta vacío o si contiene elemento/s, también encontramos una linea de comentario que dice:
Citar
// compares with 1 instead of 0
(compara con 1 en vez de 0), aclarando que lo correcto seria inicializar la variable "val" a 0, pero que aun estando inicializada a 1 se debe corregir el error lógico.

Debes usar la lógica cuando analizas este fragmento de codigo:
Código: [Seleccionar]
private int val = 1;   
      public boolean isEmpty() {
        if (val == 1) {   // compares with 1 instead of 0
          return true;
        } else {
          return false;
        }
      }
Yo lo interpreto así:

Situación ilógica: Si val (tamaño del Vector) es igual a 1 return true
(el vector esta vacío!) si no return false (el vector contiene elemento/s).

Para solucionar el error lógico, pues aplicamos la lógica.

Situación lógica: Si val (tamaño del Vector) es igual a 1 return "false" (el vector contiene elemento/s)
si no return "true" (el Vector esta vacío!).

A continuación te dejo un ejemplo de como rediseñaria yo tu ejercicio:
Código: [Seleccionar]
// import java.util.Vector; omitted
public class VectorUser
{
  public static void main(String[] args)
  {
    Vector v = new Vector();
    if (v.isEmpty())
    {
      System.out.println("Vector is empty");
    }
    else {System.out.println("Vector is NOT empty");
    }
  }
  private static class Vector //La declaración de esta clase pasa a estar dentro de la clase VectorUser.
  {
      private int val = 1;   
      public boolean isEmpty() {
        if (val == 1) {   // compares with 1 instead of 0
          return false;//anteriormente valía true
        } else {
          return true;//anteriormente valía false
        }
      }
      // other functionality is same as java.util.Vector
  }
}
Espero a ver sido bien explicito. Cualquier duda no dudes en comentar.

Saludos!
« Última modificación: 01 de Octubre 2014, 17:27 por Sniper »
while(estesVivo)
{
  aprende();
  ayuda();
  enseña();
}
if(mueres){teRecordaran();}

javi in the sky

  • Avanzado
  • ****
  • Mensajes: 393
    • Ver Perfil
Re:conflicto entre nombre de clase y clase del api de java
« Respuesta #2 en: 02 de Octubre 2014, 11:47 »
Coincido con Sniper en que el problema que tiene tu código es que hace uso de un nombre de clase (Vector) que ya existe en el api de Java, y esto genera un conflicto de nombres y posible comportamiento inesperado.

Suponiendo que lo que se quiere es obtener el mismo comportamiento que la clase Vector del api java: usaríamos esta clase, no tiene sentido redefinirla. Quedaría así:

Código: [Seleccionar]
import java.util.Vector;
public class VectorUser {
  public static void main(String[] args) {
    Vector v = new Vector();
    if (v.isEmpty()) {
      System.out.println("VectorDiferente is empty");
    } else {System.out.println("VectorDiferente is NOT empty"); }
  }
}



Suponiendo que lo que se quiere es tener un comportamiento específico y diferente de la clase Vector: le daríamos un nombre distinto a la clase para que no exista conflicto de nombres. Renombrando quedaría así:

Código: [Seleccionar]
class VectorDiferente {
  private int val = 1;
 
  public boolean isEmpty() {
    if (val == 1) {   // compares with 1 instead of 0
      return true;
    } else {
      return false;
    }
  }
  // other functionality is same as java.util.Vector
}
 
// import java.util.Vector; omitted
public class VectorUser {
  public static void main(String[] args) {
    VectorDiferente v = new VectorDiferente();
    if (v.isEmpty()) {
      System.out.println("Vector is empty");
    } else {System.out.println("Vector is NOT empty"); }
  }
}

Mi respuesta sería esta segunda opción, ya que se indica "no se debe eliminar código, sino sólo corregirlo."

Saludos!

Susana83

  • Sin experiencia
  • *
  • Mensajes: 49
    • Ver Perfil
Re:conflicto entre nombre de clase y clase del api de java
« Respuesta #3 en: 02 de Octubre 2014, 12:56 »
Gracias sniper, gracias javi, la verdad es que no se me hubiera ocurrido pensar en un "error lógico", lo que estaba buscando era un error de compilacion. Ahora por lo menos tengo claro que el error estaba en usar una clase con un mismo nombre que el api de java, lo que no acabo de tener claro es cómo tener la seguridad de que el nombre de una clase no coincide con un nombre del api de java, ya que si no salta un error de compilación veo dificil llegar a saber si estas cometiendo ese tipo de errores  :(

Jorge lopez

  • Sniper
  • Intermedio
  • ***
  • APR2.COM
  • Mensajes: 248
  • @SniperOfElite
    • Ver Perfil
Re:conflicto entre nombre de clase y clase del api de java
« Respuesta #4 en: 03 de Octubre 2014, 06:06 »
Citar
lo que no acabo de tener claro es cómo tener la seguridad de que el nombre de una clase no coincide con un nombre del api de java

Paso 1: Elegir uno de los siguientes links según la versión de java con que trabajas en tu ordenador o pc
(en mi caso uso java 8 )

java 5: http://docs.oracle.com/javase/1.5.0/docs/api/
java 6: http://docs.oracle.com/javase/6/docs/api/
java 7: http://docs.oracle.com/javase/7/docs/api/
java 8: http://docs.oracle.com/javase/8/docs/api/

(hay otras documentaciones, como java 4, 3, ext.. de las cuales no incluí links por ser muy antiguas)

Paso 2: Presionar la combinación de teclas " Ctrl + f " y escribir allí el nombre de la clase a consultar.

Paso 3: En caso de aparecer, consultar dicha clase y sus métodos a fin de comprobar si contiene lo que necesitas (de ser así, te evitara complicarte la vida. Lolz)

Paso 4: No hay paso 4 ;D

Esta seria una opción como respuesta a tu pregunta Susana83.

Si deseas conocer mas a fondo sobre el api de java, también puedes visitar el siguiente link: https://www.aprenderaprogramar.com/index.php?option=com_content&view=article&id=551:que-es-y-para-que-sirve-el-api-de-java-librerias-de-biblioteca-estandar-jdbc-javafx-rmi-cu00645b&catid=68:curso-aprender-programacion-java-desde-cero&Itemid=188

Y aun hay mas en: https://www.aprenderaprogramar.com/index.php?option=com_content&view=article&id=562:organizacion-del-api-java-principales-clases-o-librerias-y-nombres-diferencias-java-y-javax-cu00646b&catid=68:curso-aprender-programacion-java-desde-cero&Itemid=188

Saludos!
while(estesVivo)
{
  aprende();
  ayuda();
  enseña();
}
if(mueres){teRecordaran();}

Susana83

  • Sin experiencia
  • *
  • Mensajes: 49
    • Ver Perfil
Re:conflicto entre nombre de clase y clase del api de java
« Respuesta #5 en: 05 de Octubre 2014, 11:24 »
Ahora mucho más claro  ;D Explicas muy bien Sniper, aprendes ayudas y enseñas  ;)

 

Sobre la educación, sólo puedo decir que es el tema más importante en el que nosotros, como pueblo, debemos involucrarnos.

Abraham Lincoln (1808-1865) Presidente estadounidense.

aprenderaprogramar.com: Desde 2006 comprometidos con la didáctica y divulgación de la programación

Preguntas y respuestas

¿Cómo establecer o cambiar la imagen asociada (avatar) de usuario?
  1. Inicia sesión con tu nombre de usuario y contraseña.
  2. Pulsa en perfil --> perfil del foro
  3. Elige la imagen personalizada que quieras usar. Puedes escogerla de una galería de imágenes o subirla desde tu ordenador.
  4. En la parte final de la página pulsa el botón "cambiar perfil".