Autor Tema: Ejercicio! entrega CU00694B herencia y sobreescritura método equals java  (Leído 6140 veces)

Jorge lopez

  • Sniper
  • Intermedio
  • ***
  • APR2.COM
  • Mensajes: 248
  • @SniperOfElite
    • Ver Perfil
 A continuación adjunto en un archivo.rar mi propuesta sobre este ejercicio
Código: [Seleccionar]
Define una clase Figura de la que hereden otras dos clases denominadas Cuadrado y Círculo. La clase
figura debe tener al menos el campo dimensionPrincipal. Las clases Cuadrado y Círculo deben tener al
menos un método calcularArea que permita calcular el área a partir de la dimensión principal,
utilizando la fórmula matemática correspondiente. Además, sobreescribe el método equals para que
dos cuadrados sean iguales si tienen igual dimensión principal, y dos círculos idem. A continuación crea
un programa test donde crees varios círculos y cuadrados y hagas comprobaciones de igualdad usando
el método equals.
Saludos!
« Última modificación: 13 de Septiembre 2014, 11:08 por César Krall »
while(estesVivo)
{
  aprende();
  ayuda();
  enseña();
}
if(mueres){teRecordaran();}

toni_apr

  • Avanzado
  • ****
  • Mensajes: 497
  • Curiosidad, es uno de los pilares del Conocimiento
    • Ver Perfil
Re:Ejercicio! entrega CU00694B
« Respuesta #1 en: 12 de Septiembre 2014, 23:06 »
Hola Sniper
Estoy mirando tu clase 'TestDeIgualdad'
Después de hacer comparaciones con cuadrados, empiezas con los círculos viendo estas dos líneas
Citar
System.out.println ("\n\n**Resultado de comparar objetos tipo Circulo sin el metodo equals debidamente sobre escrito en la clase Circulo**");
        //Para comparar objetos de tipo circulo se invoca el metodo equals de su super clase, heredado a su vez de la clase  padre Objetc

Donde dices que vas a hacer comparaciones sin el método equals. Creo entender que haces eso a propósito, si es así, no entiendo el motivo, tal vez me puedas explicar tu razón

En la segunda línea como comentario dices que para los círculos se invoca el método equals de su clase padre o superclase, pero la clase Figura no tiene método equals.

Para mi, los dos círculos circulo1 y circulo2 deberían ser iguales (tienen la misma dimensionPrincipal) y tu código responde false a la expresión 'circulo1.equals(circulo2)'

En la clase Figura has colocado un método 'public double calcularArea()' que no usarás nunca, además devuelve un valor que no tiene sentido
'return dimensionPrincipal * PI;'
Como incluye la constante PI, no es útil para el cuadrado, y como mucho sería la longitud del círculo si dimensionPrincipal fuera el diametro del círculo

Finalmente en las clases Cuadrado y Circulo creas los atributos lado y radio respectivamente que no usas para hacer cálculos pues el atributo dimensionPrincipal sustituye al lado en un caso y al radio o diámetro según quieras en la clase Circulo

Sin descartar que tu ejercicio pueda ser valorado de forma diferente, creo que deberías replantearte el ejercicio, no se si reformar lo que tienes o hacer que lo tomas desde otra perspectiva y tal vez enfocándolo desde otro lado entras hasta el fondo del problema y lo dejas niquelado.

Saludos.

Jorge lopez

  • Sniper
  • Intermedio
  • ***
  • APR2.COM
  • Mensajes: 248
  • @SniperOfElite
    • Ver Perfil
Re:Ejercicio! entrega CU00694B
« Respuesta #2 en: 13 de Septiembre 2014, 02:03 »
 Hola toni!
Tratare de explicarme en cada punto del código, a ver si me evitas tener que rediseñarlo  ;D
 
Citar
Donde dices que vas a hacer comparaciones sin el método equals. Creo entender que haces eso a propósito, si es así, no entiendo el motivo, tal vez me puedas explicar tu razón
El método equals es un método que nace en la clase padre de todas las clases (public class Object) y por tanto es heredado en todas las demás clases, ya sean clases de la librería de java o clases que diseñemos nosotros mismos. El cometido o uso de este método es comparar igualdad entre objetos, no obstante siendo un tipo String un objeto y una instancia de clase otro objeto, no es lo mismo utilizar equals para comparar objetos tipo String que utilizarlo para comparar instancias de clases, puesto que se obtendría un resultado no real o no deseado al comparar instancias de clase. Por tal motivo es recomendable sobre escribir este método en cada clase donde se harán comparaciones entre sus instancias, indicando en el cuerpo del método las condiciones a cumplir para que dos objetos de esa clase sean iguales.

Al hacer comparaciones entre objetos de tipo Cuadrado, se obtienen resultados satisfactorios, gracias a que el metodo equals esta sobre escrito en esta clase, con las condiciones necesarias para determinar la igualdad entre instancias de esta clase.

Cual es mi intención al comparar objetos tipo Circulo usando el método equal sin sobre escribir?  Mi intención es corroborar lo que acabo de explicar, hacer ver a quien estudia este ejercicio que no es lo mismo usar el método equals sobre escrito a usarlo sin sobre escribir.

Tomando en cuenta lo que eh explicado hasta ahora, cuando dices:
Citar
Para mi, los dos círculos circulo1 y circulo2 deberían ser iguales (tienen la misma dimensionPrincipal) y tu código responde false a la expresión 'circulo1.equals(circulo2)'
En cierto punto estas en lo correcto, no solo tienen la misma dimensionPrincipal, sino que también tienen el mismo radio y el mismo PI, pero si te fijas estoy usando el método equals no sobre escrito para compararlos, por tanto es normal que devuelva un resultado no deseado (false)

Citar
//Para comparar objetos de tipo circulo se invoca el método equals de su super clase, heredado a su vez de la clase  padre Objetc
En este comentario parece que me explique mal, lo que quise decir es que el equals que se ejecuta es el de la clase Object, puesto que el compilador busca este método primero en la clase Circulo, no lo encuentra y pasa a la clase Figura, tampoco lo encuentra sobre escrito en esa clase, hasta que final mente lo encuentra en la clase Object, pero las condiciones a cumplir en el cuerpo de el método equals de la clase Object, no son las correctas para determinar la correcta igualdad entre circulo1 y circulo2, de aquí proviene  el "error" ¿Son iguales el circulo1 y el circulo2? false.

Citar
En la clase Figura has colocado un método 'public double calcularArea()' que no usarás nunca, además devuelve un valor que no tiene sentido
'return dimensionPrincipal * PI;'
Como incluye la constante PI, no es útil para el cuadrado, y como mucho sería la longitud del círculo si dimensionPrincipal fuera el diámetro del círculo
Sobre esto, estoy de acuerdo contigo en cuanto al método, mientras estuve diseñando el código me surgió la necesidad de crear este método, para que las sub clases Cuadrado y Circulo lo hereden de Figura,  intente crearlo sin contenido entre las llaves, porque solo me interesaba sobre escribirlo en las sub clases, pero al ser un método tipo funcion, esto no me fue posible, ahora que e estudiado la entrega CU00695B me doy cuenta que lo que yo necesitaba era un método abstracto (sin cuerpo) pero no pude descubrirlo sin antes estudiar la entrega CU00695B ;D

Citar
Finalmente en las clases Cuadrado y Circulo creas los atributos lado y radio respectivamente que no usas para hacer cálculos pues el atributo dimensionPrincipal sustituye al lado en un caso y al radio o diámetro según quieras en la clase Circulo
Es cierto que los atributos lado y radio, no son necesarios (En referencia al ejercicio) pero veo mas prudente que una clase ademas de contener los atributos y métodos que hereda de su super clase, también cuente con atributos y métodos propios (No es obligatorio). Si te fijas en la clase 'TestDeIgualdad' aparece esta fracción de código:
Código: [Seleccionar]
circulo3.setRadio(4.5);la cual tiene como objetivo, hacer al objeto circulo3 diferente a los objetos circulo1 y circulo2, independientemente del resultado erróneo de la comparación, por tanto en este punto se le encuentra utilidad al atributo radio y al método setRadio() de la clase Circulo
aunque también pude invocar al método setDimensionPrincipal() para lograr esta diferencia.

Espero haberme explicado de manera que me entiendas, si aun crees que debo replantear el ejercicio pues me pondré manos a la obra.

Muchas gracias por revisar mi ejercicio toni.

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

toni_apr

  • Avanzado
  • ****
  • Mensajes: 497
  • Curiosidad, es uno de los pilares del Conocimiento
    • Ver Perfil
Re:Ejercicio! entrega CU00694B
« Respuesta #3 en: 13 de Septiembre 2014, 09:53 »
Hola Sniper.
Creo entender tus explicaciones. Además de realizar el ejercicio, incluyes también lo que no debe hacerse al comparar objetos 'usar el método equals no sobreescrito'

Si has de rehacer el ejercicio, es elección tuya.
Este es tu ejercicio y si para ti cumple sus espectativas, está bien.

Así pues, acepto tus razones.
Pero desde mi punto de vista. ¿No debías indicar en el ejercicio que hacías esta comparación con resultados falsos?
Algo como:
Observar como la siguiente comparación da una respuesta errónea.
Y comentar la explicación que das ahora. Que el compilador ha subido de superclase en superclase hasta encontrar un método equals que obiamente no está adaptado a este caso particular y por eso da false en una comparación que debía dar true.
Yo habría echo eso.
Es mi opinión.

En cuanto al método 'calcularArea()' de la clase Figura, entiendo que querias sobreescribirlo después, pero que el compilador no te dejaba poner un método tipo función sin devolver un valor, y que ahora sabes que podías usar un método abstracto.
Eso puede decir dos cosas:
Que con lo que sabes ahora vas a hacer una adaptación del código para que esta función  no quede en el aire
O que es un método inoperante y lo vas a eliminar.

Por último. Los métodos 'calcularArea' de las clases Cuadrado y Circulo, no usan el atributo lado ni radio para calcular el área, sino el parámetro dimensionPrincipal.

Si que usas lado en el método equals para comparar dos cuadrados, pero como en la clase Circulo no tienes método equals. Volvemos al principio, se usa un método equals que tu has demostrado que da false.
Es decir, comparar circulo1 y circulo3 con equals no da false porque circulo3 tenga un radio distinto, sino porque se usa un método equals no sobreescrito.

Estoy abierto a tus comentarios.

Saludos.

César Krall

  • Moderador Global
  • Experto
  • *******
  • Mensajes: 2078
  • No vales por lo que dices, sino por lo que haces
    • Ver Perfil
    • aprenderaprogramar.com
Re:Ejercicio! entrega CU00694B
« Respuesta #4 en: 13 de Septiembre 2014, 11:07 »
Hola Sniper, te comento mi punto de vista:

Las indicaciones que te ha dado toni son correctas.

Cuando dices:

Cual es mi intención al comparar objetos tipo Circulo usando el método equal sin sobre escribir?  Mi intención es corroborar lo que acabo de explicar, hacer ver a quien estudia este ejercicio que no es lo mismo usar el método equals sobre escrito a usarlo sin sobre escribir.


Aquí estás incumpliendo con lo que pide el ejercicio: estás introduciendo una variación que correspondería a que el ejercicio pidiera "Haz uso del método equals con dos círculos sin sobreescribir el método equals en esta clase para comprobar que no se obtiene un resultado correcto"

Desde el momento en que incumples lo que pide el ejercicio y no se ve una explicación o lógica clara de lo que estás haciendo, no puede decirse que el ejercicio esté bien. Este tipo de pruebas está bien hacerlas, pero uno mismo para hacer comprobaciones ó explicando muy bien lo que se ha hecho. De otra manera creas confusión, y quien lea o revise el ejercicio no va a entender lo que has hecho.

Decir que dos círculos tienen el mismo PI no es correcto. PI es una constante matemática, una relación L = Pi * D, y Pi = L / D. Es decir, Pi es un valor constante que se obtiene siempre que se divide la longitud de un círculo entre su diámetro. Pero no es una propiedad de un círculo, no podemos decir "este círculo tiene el mismo Pi que este otro" porque eso carece de sentido.


Comentas: <<Es cierto que los atributos lado y radio, no son necesarios (En referencia al ejercicio) pero veo mas prudente que una clase ademas de contener los atributos y métodos que hereda de su super clase, también cuente con atributos y métodos propios>>

Aquí no tienes claros los conceptos: un concepto básico es que la información y el código no debe repetirse. Desde el momento en que el atributo dimensionPrincipal representa el lado del cuadrado, volver a declarar un atributo y métodos get y set para lado lo que hacen es repetir información ¡Mal diseño de un programa! La herencia la utilizas para reutilizar código y evitar repetición, si haces lo contrario... mala concepción de un programa.

<<aunque también pude invocar al método setDimensionPrincipal() para lograr esta diferencia>> ... pues esto es lo que tenías que haber hecho ¡Reutilización del código!

Desde mi punto de vista el ejercicio es incorrecto y debería ser reescrito. Por las explicaciones que das parece que manejas bien los conceptos pero después el código refleja lo contrario. El código no puede considerarse bueno, aunque como dice toni, rehacerlo es elección tuya...

Saludos!
Responsable de departamento de producción aprenderaprogramar.com

Jorge lopez

  • Sniper
  • Intermedio
  • ***
  • APR2.COM
  • Mensajes: 248
  • @SniperOfElite
    • Ver Perfil
Re:Ejercicio! entrega CU00694B herencia y sobreescritura método equals java
« Respuesta #5 en: 15 de Septiembre 2014, 22:32 »
 Nunca te creas sabio en tu propia opinión, reconoce tus horrores y aprende de ellos.

Reconozco que mi ejercicio no se adapta a lo que requiere el ejercicio, aun cuando creo dominar bien los conceptos de igualdad e identidad de objetos.

Gracias toni, gracias cesar por corregir me.

Aquí dejo un archivo.rar con lo que es el replanteamiento de este ejercicio.

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

toni_apr

  • Avanzado
  • ****
  • Mensajes: 497
  • Curiosidad, es uno de los pilares del Conocimiento
    • Ver Perfil
Re:Ejercicio! entrega CU00694B herencia y sobreescritura método equals java
« Respuesta #6 en: 16 de Septiembre 2014, 21:17 »
Hola Sniper
Las clases en que defines objetos, Figura, Cuadrado y Circulo, perfectas con sus métodos sobreescritos y además indicándolo con el @Override
El código, bien. Todo lo que has puesto es correcto.
Se que los conceptos los tienes claros, lo dices tu mismo y he visto en el foro que te lo dicen los moderadores.

Respecto a la clase, TestDeIgualdadEIdentidad he de decir que el código también está bien.
En cuanto al estilo en la presentación del trabajo.
Es tu propio estilo, un estilo propio, que a ti te debe gustar y espero que lo vayas puliendo con el tiempo hasta que hagas unas presentaciones que no solo de gusto ver, sino que uno quiera volver a ver para disfrutarlas.

Eso es todo

Ahora, quiero pedir tu opinión respecto al código que te envío.
Es una clase para cifrar texto.
Para que la pruebes te mando este texto cifrado

"Trvmv fm zotlirgnl wv xruizwl nfb hvmxrool. Pvil xlm oz klhryrorwzw wv szxviol gzm vmivevhzwl xlnl fml jfrviz"

Código: [Seleccionar]
public class Encript {           
    private static String base =        "abcdefghijklmnopqrstuvwxyz";
    private static String baseCifrado = "zyxwvutsrqponmlkjihgfedcba";
    public static void ado(String textoEntrante) {
        String textoSaliente = "";
        String caracter = "";
        int posicion = 0;
        for (int i = 0; i < textoEntrante.length();i++) {
            caracter = textoEntrante.substring(i,i+1);
            posicion = base.lastIndexOf(caracter);
//             System.out.println ("caracter -" + caracter + "- posicion " + posicion);
            if (posicion != -1) {
                textoSaliente = textoSaliente + baseCifrado.substring(posicion,posicion+1);
            } else {
                textoSaliente = textoSaliente + caracter;
            }
        }
        System.out.println ("Texto entrante: " + textoEntrante + "\nTexto saliente: " + textoSaliente);
//Este codigo funciona tanto para cifrar como para descifrar
    }
} // Fin de la clase Encript

En una clase con main escribes
Encript.ado("Texto a cifrar");

Saludos

Jorge lopez

  • Sniper
  • Intermedio
  • ***
  • APR2.COM
  • Mensajes: 248
  • @SniperOfElite
    • Ver Perfil
Re:Ejercicio! entrega CU00694B herencia y sobreescritura método equals java
« Respuesta #7 en: 19 de Septiembre 2014, 02:06 »
 Hola toni!

1ro gracias por verificar y comentar mi ejercicio  ;)

En cuanto a mi opinión sobre tu clase Encript, tengo para decirte que lo primero que hice al descifrar el texto que me dejaste para que pruebe, fue no entender nada  ;D, el algoritmo que usas para un "programador" de mi nivel, no es nada sencillo a menos que no profundices y comprendas el método lastIndexOf(String str); de la clase String.

En principio trate de buscar un patrón para ver como se comportaba el algoritmo, solo introduciendo cadenas cortas e intentando identificar un patrón, luego de pocos intentos decidí mejor mirar tu código e identificar algo extraño o que no hubiese visto antes, entonces veo el método lastIndexOf(String str); y buscando detalles en la librería de java, encontré estos detalles sobre el método: Devuelve el índice dentro de esta cadena de la última aparición de la subcadena especificada. La última aparición de la cadena vacía "se considera" que se produzcan en el valor del índice this.length ().
donde llegue a la conclusión de que si la variable base tuviera un valor como base = "abca" el valor posición de "a" no fuese 0 sino 3.

Estoy muy de acuerdo contigo cuando dices que este algoritmo tiene posibilidades de ser bassstante enrevesado.

En general me a gustado bastante tu código y me tome la libertad de hacer algunos reajustes (esto no le resta méritos a tu diseño, al contrario! me quito el sombrero), los cuales me gustaría que analices y comentes.

Citare un pequeño cambio de signatura o declaración: Las variables base y baseCifrado pasaron de ser variables generales de la clase, a variables locales del método ado(); esto lo veo mas conveniente, porque estas variables no son intervenidas por métodos setters o getters

Los demás cambios son funcionales respecto al comportamiento del algoritmo, veras un comentario (cifrado  ;D) en cada fragmento de código añadido.

Aqui te dejo el codigo:
public class Encript
Código: [Seleccionar]
public class Encript
{
    //Sin variables generales
    public Encript()
    {
      //Constructor general (vacio)
    }
    public static void ado(String textoEntrante)
    {   
        String base =        "abcdefghijklmnopqrstuvwxyz";
        String baseCifrado = "zyxwvutsrqponmlkjihgfedcba";
        String textoSaliente = "";
        String caracter = "";
        int posicion = 0;
        String tipoCaracter = "";
        //Para poder leer los siguientes primeros 3 comentarios, favor decifrarlos pasandolos como parametro tipo String en la invocacion de ese metodo.
        for (int i = 0; i < textoEntrante.length();i++)
        {
            caracter = textoEntrante.substring(i,i+1);
            //Vhgv ru xlm vohv ru, zfnvmgz oz vuvxrvmxrz wvo xlwrtl zo kvinrgri zo zotlirgnl vezofzi ovgizh (jfv gznyrvm hlm xzizxgvivh) nzbfhxfozh b nrmfhx.
            if(caracter.equals(caracter.toUpperCase())){base = base.toUpperCase(); baseCifrado = baseCifrado.toUpperCase();}
            else if(caracter.equals(caracter.toLowerCase())){base = base.toLowerCase(); baseCifrado = baseCifrado.toLowerCase();}
            posicion = base.lastIndexOf(caracter);
            //Vhgv hdrgxs grvmv oz hvmxrooz gzivz wv zhrtmzi fm ezoli z oz ezirzyov grklXzizxgvi, xfbz ezirzyov hviz fhzwz kziz nlhgizi nvmhzqvh kli kzmgzooz
            switch(posicion)
            {
              case -1: tipoCaracter = "Caracter-";break;
              default: tipoCaracter = "Letra----";
            }
            //Vm vhgv Hbhgvn.lfg.kirmgom oz ezirzyov grklXzizxgvi rmwrxz xfzmwl vh fm xzizxgvi grkl ovgiz, l fm xzizxgvi vm hr.
            System.out.println (tipoCaracter + "-" + caracter + "- posicion " + posicion);
            if (posicion != -1)
            {
                textoSaliente = textoSaliente + baseCifrado.substring(posicion,posicion+1);
            }
            else
            {
                textoSaliente = textoSaliente + caracter;
            }
        }
        System.out.println ("\nTexto entrante: " + textoEntrante + "\nTexto saliente: " + textoSaliente);
        //Este codigo funciona tanto para cifrar como para descifrar
    }
} // Fin de la clase Encript

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

toni_apr

  • Avanzado
  • ****
  • Mensajes: 497
  • Curiosidad, es uno de los pilares del Conocimiento
    • Ver Perfil
Re:Ejercicio! entrega CU00694B herencia y sobreescritura método equals java
« Respuesta #8 en: 19 de Septiembre 2014, 21:14 »
Si Sniper
Me gusta lo que le has añadido.
Ahora, también funciona con las mayúsculas.

Cuando inicialicé

String base = "abcdefghijklmnopqrstuvwxyz";

Solo con minúsculas, me dije a mí mismo. Para qué añadir las mayúsculas, total solo habrá una, dos o tres a lo sumo.
Pero he visto que no hay problema.
Con un poco de código problema arreglado.

Xfzgil lqlh evh náh jfv wlh

A parte, de lo que dices de

lastIndexOf()

Ya tengo en cuenta que devuelve la última ocurrencia del texto que le doy. Pero como no repito ninguna letra en

String base = "abcdefghijklmnopqrstuvwxyz";

Funciona perfecto.

Saludos

 

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".