Inheritance com equals

Bom, gente eu to iniciando e ta pegando aqui uma duvida em como aplicar numa subclass um metodo que ja defini numa super class abstract.
Eu tenho uma classe Item e dela saem classes CD e DVD, entao ja configurei o metodo equals na Item e so quero adicionar um parametro na equals na classe CD por exemplo. Ai abaixo tao os codigos das duas, o primeiro e do metodo equals da Item e o segundo de CD. O metodo na Item compilou, mas nao ta dando pra compilar esse metodo na classe CD. Por que? e assim que se faz?

Obrigado!

[b]

public boolean equals(Object o) // metodo da classe Item
{
if ((o instanceof Item) && ((((Item) ).getTitle()).equals(getTitle())) && ((((Item)).getArtist().equals(getArtist()))
&& ((((Item) o).getComments()).equals(getComments())) && ((((Item) o).getLength()) == (getLength()))))
return true;

    else
        return false; 
}

[/b]

[b]
public boolean equals(Object o) // metodo da classe CD
{
if (!(o instanceof CD))
return false;
CD tester = (CD) o;
return (super.equals(o) && (tester.getNumOfTracks() == o.getNumOfTracks()));

}

[/b]

eu bem que tentei mas os seus métodos são um tanto confusos.

Vc poderia definir o que faz um CD ser igual ao outro, assim como o DVD.

Me parece que a sua classe Item é abstrata. Algo como

[code]abstract class Item{
// aqui : deixe o equals em paz
}
class CD extends Item{
public boolean equals(Object o){
System.out.println(“equals do CD”);
return …;
}
}
class DVD extends Item{
public boolean equals(Object o){
System.out.println(“equals do DVD”);
return …;
}
}

public class Test{
public static void main(String [] args){
Item x = new CD();
Item y = new DVD();

    assert !x.equals(y); // -> equals do CD
    assert !y.equals(x); // -> equals do DVD
}

}[/code]

IMHO a sua classe Item tem um jeitão de classe abstrata. Tu vende um item? Tem la na prateleira um item? É provavel que tenha um CD ou um DVD, que são itens. mas um item “puro” eu acho dificil (nesse caso é só pra reuso de código…).

Se você usar o instanceof no seu método equals, vai violar o contrato do método.

Isso porque, ao adicionar mais um campo no equals do seu CD, você corre o risco do seguinte:

item.equals(cd); //True
cd.equals(item); //False

Imagine um item e um CD com todos os campos que tem em comum iguais. No primeiro equals (o do item), CD instanceof item e todos os métodos são iguais, logo, equals retorna true. No segundo caso, item não é um instanceof CD, e o método equals retorna false.

E, pelo contrato, o equals deve ser simétrico. Para resolver isso, substitua o instanceof por uma comparação direta da classe:

if (getClass() != o.getClass()) return false;

A classe Item e abstrata, mas eu quero definir o equals na classe Item para poder nao precisar defini-lo completamente em CD e em DVD. Fora que se eu quiser ainda criar outras classes que sejam fita cassete ou algo do genero, nao precise escrever tudo de novo no equals.

Se eu tirar o instanceof, como funciona com o lance do super.equals(o) ? Ta certo esse comando?
Obrigado pelas respostas

Ok, mas mesmo no caso do super, faça com o getClass() e não com instanceof.

Isso garante que um CD nunca será igual a um DVD, em hipótese alguma. Do jeito que está, o instanceof compara com a classe item, não com a do item específico. Assim você garante a simetria, mesmo nos casos onde as classes filhas de item não tiverem implementação específica. :wink: