Solucionado (ver solução)
Solucionado
(ver solução)
4
respostas

HASHCODE - EQUALS

Quanto eu tento sobrescrever os métodos equals() e hashCode() em subclasses, usando o "Generate hashCode() and equals()" do Eclipse, este retorna o erro "there are no non-static fields in this class. Cannot create equals() and hashcode() methods" Como se não enxergasse os atributos da classe estendida. É possível contornar este problema?

Dado este problema eu fiz o "Generate hashCode() and equals()" na superclasse e adicionei a primeira condição no equals(): if(this.getClass..), para que ao invocar o equals() em objetos de diferentes subclasses o retorno seja false. Porém o hashCode() continua retornando o mesmo para objetos de diferentes subclasses com o mesmo 'numero', alguém pode me ajudar com isto? Obs: 'numero' é um atributo da superclasse tipo uma ID.

    @Override 
    public boolean equals(Object obj) {
        if (this.getClass().equals(obj.getClass()) == false) 
            return false; 
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (!(obj instanceof Conta))
            return false;
        Conta other = (Conta) obj;
        if (numero != other.numero)
            return false;
        return true;


    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + numero;
        return result;
    }

    }
4 respostas

Guilherme, você pode postar as classes inteiras pra gente dar uma olhada?

package br.com.empresa.banco.conta;

public abstract class Conta implements Comparable<Conta> {

    protected double saldo;
    protected int numero;
    protected String nome;

    public double getSaldo() {
        return this.saldo;
    }

    /**
     * realiza um deposito na conta dado o valor passado
     * 
     * @param valor
     *            valor a ser depositado
     * @throws ValorInvalido
     *             caso o valor seja menor ou igual a zero
     */

    public void deposita(double valor) throws ValorInvalido {
        try {
            if (valor > 0)
                this.saldo += valor;
            else
                throw new ValorInvalido(valor);
        } catch (ValorInvalido e) {
            System.out.println(e);
        }
    }

    public void saca(double valor) {
        this.saldo -= valor;
    }

    public abstract void atualiza(double taxa);

    @Override
    public String toString() {
        return ("A conta: "+this.nome + " tem saldo: " + this.saldo);

    }

    //@Override
    //public boolean equals(Object obj) {
    //    return (this.numero == (((Conta) obj).numero) && (this.nome == ((Conta) obj).nome));
    // }

    public String getNome() {
        return nome;
    }

    public void setNome(String nome) {
        this.nome = nome;
    }

    public int getNumero() {
        return numero;
    }

    public void setNumero(int numero) {
        this.numero = numero;
    }


    //para funcionar o sort nas collenctions
    @Override
    public int compareTo(Conta outra) {
        return this.nome.compareTo(outra.nome);
    }

    //public int compareTo(Conta outra) {
        //return this.saldo - outra.saldo;
    //}

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + numero;
        return result;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (!(obj instanceof Conta))
            return false;
        Conta other = (Conta) obj;
        if (numero != other.numero)
            return false;
        return true;
    }


}
package br.com.empresa.banco.conta;

public class ContaCorrente extends Conta implements Tributavel {

    public void atualiza(double taxa) {
        this.saldo += 2 * taxa * this.saldo;
    }

    public double calculaTributos() {
        return (0.01 * this.getSaldo());
    }

}
package br.com.empresa.banco.conta;

public class ContaPoupança extends Conta{


    public void atualiza(double taxa){
        this.saldo += 3*taxa*this.saldo;
    }



    public void deposita(double valor){
        this.saldo += valor - 0.1;
    }
}

Seu código está correto! Em subclasses há sempre um problema a ser enfrentado: uma conta corrente que tem mesmo id e saldo que uma conta poupanca sao iguais? se sim, deixa o codigo como está. Caso negativo, precisa reescrever ambos os métodos e fazer o instanceof! Caso seja do mesmo tipo, joga para o super da sua classe! Nesse seu caso em particular, o hashCode da mãe serve, já que na filha voce nao tem atributos a mais.

solução!

O hashcode da super classe faria um instanceof comparando apenas apenas sua própria classe, não iria diferir as subclasses, encontrei essa solução:


    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + numero;
        result = prime * result + this.getClass().hashCode();
        return result;
    }

    @Override
    public boolean equals(Object obj) {
        if (this.getClass() != obj.getClass()) 
            return false;
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (!(obj instanceof Conta))
            return false;
        Conta other = (Conta) obj;
        if (numero != other.numero)
            return false;
        return true;
    }

}

Agora tanto o hashCode e o equals diferem as subclasse, mantendo o contrato de Object.