2012-02-29 23 views
5

Esto es para un programa de fracciones. Tengo ints privados num y den, Fraction, y FractionInterface - el problema estándar de tarea. He hecho casi todo y ahora he estado estancado por unas horas en el método de igualdad. Como other es un Object, no puedo equipararlo a Fraction. Aquí es lo que tengo:public boolean equals (Object other)

public boolean equals(Object other){   
    if (other == this){ 
     return true; 
    } else { 
     return false; 
    } 
} 

Este compila pero da resultados incorrectos:

1/2 eq 1/2 = true 
1/2 eq 1/2 = true 
1/2 eq 1/2 = false 
1/2 eq 1/2 = false 

Si lo intento otra fracción ==, no compila. ¡Gracias por cualquier ayuda!

+1

¿Sabes qué clases vienen como 'otras'? Además, ¡+1 para marcar esta tarea y una pregunta bien planteada! – macduff

+0

Tenga en cuenta que la mayoría de las respuestas hasta ahora fallarán si 'other' implementa' FractionInterface' pero no es de clase 'Fraction'. Debe tener claro si desea una solución que funcione solo cuando 'other' sea una instancia de' Fraction', o una que funcione cuando 'other' sea una instancia de' Fraction' o una de sus subclases, o una eso funciona para cualquier objeto que implemente 'FractionInterface'. Necesita un código diferente para cada caso. –

Respuesta

1

Trate de hacer esto:

En primer lugar, emitir el other objeto

Fraction otherFraction = (Fraction) other; 

Entonces, determinar la condición de que las dos fracciones son equivalentes. Esto incluirá alguna lógica que implica la comparación de numerador y denominador (espera utilizar getNum() y getDen() para la otherFraction.

+2

Esto podría explotar si otro es del tipo incorrecto. –

+0

¡Gracias! Ya había intentado lanzar el "otro" objeto como dijiste, pero en lugar de obtener el numerador y el denominador, intenté compararlo directamente con la otra fracción. Otro error simple que estaba cometiendo. Funciona ahora, usando los métodos Get y la multiplicación cruzada. ¡¡Gracias de nuevo!! – Boris4ka

+0

Buena llamada James. Recuerdo que en mi clase AP Java no se esperaba que hiciéramos nada sobre el hecho de que esta afirmación puede explotar. Sin tener que introducir el reflejo, podría sugerirles a los principiantes que intenten incluir cosas en declaraciones try-catch. –

0

necesita probar si el objeto tiene la clase de fracciones, y si es así, lo echarás a una fracción:

if (other.getClass() != Fraction.class) { 
    return false; 
} 
Fraction otherFraction = (Fraction) other; 
// compare the fields of this and otherFraction 

Antes de hacer esto, asegúrese de probar también para nulo.

+1

Por curiosidad, ¿por qué no utilizar 'instanceof'? –

+0

Porque si Fraction se extiende y la subclase anula equals, el uso de instanceof rompería el contrato de iguales: 'fraction.equals (subFraction)' sería verdadero, mientras que 'subFraction.equals (fraction)' sería falso. –

+0

Es muy difícil de implementar es igual a 'instanceof' si Fraction tiene subclases, por lo que getClass es una alternativa popular. – Joni

0

Está comparando que las dos referencias de objetos hacen referencia al mismo objeto.

Deberá comprobar que el other es del tipo Fraction y luego emitirlo a Fraction. A continuación, comparará las dos partes del Fraction.

2

Puede probar si other es una instancia de FractionInterface y utilizar un reparto:

public boolean equals(Object other){   
    if (other == this){ 
     return true; 
    } else if (other instanceof FractionInterface) { 
     FractionInterface fOther = (FractionInterface) other; 
     // compare numerator and denominator... 
    } else { 
     return false; 
    } 
} 

Tenga en cuenta que habrá instanceoffalse si other == null, así que no hay necesidad de un cheque nulo separado.

1

debe comprobar si el argumento es una instancia de la clase y regresa false si no es fundido y a su clase y comparación de acuerdo a sus necesidades si es es común escribir equals() método como este:.

public boolean equals(Object obj) { 
    if (!(obj instanceof Fraction)) { 
     return false; 
    } 
    Fraction that = (Fraction) obj; 
    ... // Your algorithm to compare two fractions: this and that. 
} 

Usted debe asegurarse de que su algoritmo para comparar dos fracciones cumple con todos los requisitos descritos en equals()documentation.

-1

== operador compara códigos hash de objetos. Eso es por lo que el método no funciona, se debe escribir así:

public boolean equals(Object other){   
    if (other instanceof Fraction){ 
     return ((Fraction)other).getNum == this.num && ((Fraction)other).getDen == this.den; 
    } else { 
     return false; 
    } 
} 
+3

¡Esto está mal! == compara lo que está almacenado en la pila. Para las primitivas, este es el valor acctual y para los objetos es la referencia al montón allí donde se almacena el objeto. El hashcode debe ser igual para dos objetos porque habrá problemas y luego usar hashmaps – nist

+0

Sí, tienes razón, mi mal. Era tarde en la noche cuando escribía la respuesta :) –

0

creo que está cerca, pero que se está perdiendo algunos conceptos clave. Esto se debe a que su "tal cual" no funcionará en todas las situaciones. Pruebe esto, por ejemplo, usando su código existente ...

Fraction a = // this is however you're making a fraction object... 
Fraction b = // do EXACT same thing here that you did for a 

// And then, this will illustrate what is wrong with your program... 
if(a.equals(b)) { 
    System.out.println("This won't print"); 
} else { 
    System.out.println("This will print because your method just checks for reference"); 
} 

Así que aquí están los conceptos básicos que hay que entender:

  1. Diferencia entre == y equals
  2. Comparando tipo en lugar de hacer referencia o valor
  3. Evitar la fundición poniendo su "es igual a" método en el lugar correcto

Primero de ...

public boolean equals(Object other){   
    if (other == this){ 
     return true; 
    } else { 
     return false; 
    } 
} 

Te estás perdiendo el punto del método "igual" en Java. == se usa para comparar referencias, mientras que this.equals(foo) se usa para poner la lógica para comparar objetos en un lugar localizado.

El otro concepto que te falta es cómo se debe usar instanceof. Cuando se le pregunta esto ...

Si intento otro == Fracción, no se compila.

Esto es porque estás buscando comparar el tipo de objeto. Para ello, sólo tendría que hacer ...

if(other instanceOf Fraction) { 
    // do stuff... 
} 

Todo eso se dice, hay un último concepto, que está poniendo la definición iguales en el lugar adecuado. Es necesario poner dentro de su clase Fracción y definir así ...

public boolean equals(Fraction other) { 
    // do something like this (you will have to define toDouble) 
    if(this == other || this.toDouble() == other.toDouble()) { 
    return true; 
    } 

    return false; 
} 

Esto anulará el valor por defecto ...

public boolean equals(Object other) {/* ... */} 

y hará que sea muy conveniente. Aquí hay un código de ejemplo de cómo ...

Fraction fractionA = new Fraction("2/4"); 
Fraction fractionB = new Fraction("1/2"); 
Fraction fractionC = new Fraction("1/3"); 
Object trollObject = new Object(); 

// And then call random equals objects... 
if(fractionA.equals(fractionB)) { 
    // should be true... 
} 

if(fractionB.equals(fractionA)) { 
    // should be true... 
} 

// This avoids having to do any casting because 
// since you've only defined a Fraction.equals(Fraction) method 
// it should instead default to the Object.equals method 
if(trollObject.equals(fractionB)) { 

} 
0

Aquí está un patrón bastante estándar:

public boolean equals(Object other) { 
    if (other == this) return true; 
    if (other == null) return false; 
    if (other.getClass() != this.getClass()) return false; 

    Fraction o = (Fraction) other; 
    // now you compare their num, den, and possibly sign 
} 

La gente puede discutir si debemos utilizar getClass() o instanceof. Solo importa si se extiende Fraction, y depende de lo que desee si se extiende. Solo tenga en cuenta que un contrato de equals() es a.equals(b) debe obtener el mismo resultado que b.equals(a) si ninguno es null, y una subclase puede tener un equals() diferente que potencialmente puede romper el contrato.

+0

Esto tampoco funcionará si 'other' no es' Fraction' sino algún otro objeto que implemente 'FractionInterface'. –

+0

Derecha. Realmente depende de lo que quieras si 'other' no es' Fraction' sino que implementa 'FractionInterface'. Es un área gris En caso de duda, prefiero devolver 'false'. Si 'other' tiene un campo' sign' adicional y no tenemos acceso a él, simplemente debemos devolver 'false' –

-1

Espero que te sea útil .haga este código.

import java.io.*; 

class Cast 

{ 

public static void main(String args[]) throws IOException 

{ 

BufferedReader br=new BufferedReader(new InputStreamReader(System.in)); 

byte a=20; 

short s=31468; 

int i=12345678; 

char c=’c'; 

float f=3.56f; 

//Widening or promotion [java question bank][1] 

System.out.println(“a=(short) “+(short) a); 

System.out.println(“a=(int) “+(int) a); 

System.out.println(“a=(long) “+(long)a); 

System.out.println(“a=(float) “+(float)a); 

System.out.println(); 

System.out.println(); 

System.out.println(“s=(int) “+(int)s); 

System.out.println(“s=(long) “+(long)s); 

System.out.println(“s=(float) “+(float)s); 

System.out.println(); 

System.out.println(); 

System.out.println(“i=(long) “+(long)i); 

System.out.println(“i=(float) “+(float)i); 

System.out.println(“i=(double) “+(double)i); 


//Narrowing using [java question bank][2] 

System.out.println(“f=(byte) “+(byte)f); 

System.out.println(“f=(short) “+(short)f); 

System.out.println(“f=(char) “+(char)f); 

System.out.println(“f=(long) “+(long)f); 

System.out.println(); 

System.out.println(); 

System.out.println(“i=(byte) “+(byte)i); 

System.out.println(“i=(short) “+(short)i); 

System.out.println(); 

System.out.println(); 

System.out.println(“s=(byte) “+(byte)s); 


} 

} 
+0

No estoy seguro de que esto ayude al OP. ¿Cuidado para elaborar? – GHC

Cuestiones relacionadas