Ir para o conteúdo
  • Revista PROGRAMAR: Já está disponível a edição #60 da revista programar. Faz já o download aqui!

msr

Abstract class, equals() e subclasses

Mensagens Recomendadas

msr

Olá,

Tenho uma classe abstracta chamada Xpto e duas subclasses que a estendem chamadas Pessoa e Carro.

Tenho também a classe Teste que tem a main() e que pretende ver se duas pessoas ou carros são iguais. Para isso redefini o método equals() quer na classe Pessoa quer na classe Carro, definindo que duas pessoas são iguais se tiverem nome igual e que dois carros são iguais se tiverem matrícula igual.

No entanto ao chamar o equals() na na classe teste tenho sempre "false" e até percebo porquê: não tenho redefinido o equals() na classe Xpto. Mas então como é que consigo ver se duas pessoas ou carros são iguais a partir da main()? O método foo() deve receber objectos de qualquer classe que extenda a classe Xpto e verificar se são iguais.

Resumindo, o código que tenho é este:

public abstract class Xpto {


}

public class Pessoa extends Xpto{

protected String nome;

public Pessoa(String nome){
	this.nome = nome;
}

public boolean equals(Pessoa p){
	System.out.println("Pessoaequals()?");
	return this.nome.compareTo(p.nome) == 0 ? true : false;
}
}

public class Carro extends Xpto{
protected String matricula;

public Carro(String matricula){
	this.matricula = matricula;
}

public boolean equals(Carro carro){
	System.out.println("Carro equals()?");
	return this.matricula.compareTo(carro.matricula) == 0 ? true : false;
}
}

public class Teste {

public static void foo(Xpto xpto1, Xpto xpto2){
	if(xpto1.equals(xpto2))
		System.out.println("xpto1.equals(xpto2) -> true");
	else
		System.out.println("xpto1.equals(xpto2) -> false");

}

public static void main(String argv[]){
	Carro c1 = new Carro("ABC");
	Carro c2 = new Carro("DEF");
	Pessoa p1 = new Pessoa("Manel");
	Pessoa p2 = new Pessoa("Manel");

	foo(p1,p2);
}
}

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
M6

Consegues ver isso assim:

1. alteras o teu desenho (que me parece errado dado que Carro e Pessoa na verdade partilham o método equals;

2. com identificação dos tipos e cast:

   public static void foo(Xpto xpto1, Xpto xpto2) {
      boolean eq = false;
      if (xpto1 instanceof Carro) {
         eq = ((Carro)xpto1).equals((Carro)xpto2);
      }else if (xpto1 instanceof Pessoa) {
         eq =((Pessoa)xpto1).equals((Pessoa)xpto2);
      }
      if (eq)
         System.out.println("xpto1.equals(xpto2) -> true");
      else
         System.out.println("xpto1.equals(xpto2) -> false");
   }


10 REM Generation 48K!
20 INPUT "URL:", A$
30 IF A$(1 TO 4) = "HTTP" THEN PRINT "400 Bad Request": GOTO 50
40 PRINT "404 Not Found"
50 PRINT "./M6 @ Portugal a Programar."

 

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
Baderous

Eu acho que essa forma de resolver não está muito correcta porque está-se a misturar castings com determinação de tipos dinâmicos num método da classe de teste. A solução que considero correcta passa por declarar o método equals na classe Xpto como sendo abstracto, fornecendo depois a implementação concreta do mesmo nas suas subclasses. Depois basta, na classe de teste, fazer a chamada do método equals entre 2 instâncias de Xpto, sendo que o interpretador consegue determinar, em tempo de execução, qual o tipo dinâmico destas instâncias (Pessoa ou Carro), invocando o método equals definido na classe representativa dessa instância:

public abstract class Xpto {

        public abstract boolean equals(Object o);
}

public class Pessoa extends Xpto {
        private String nome;

        public Pessoa(String n) { this.nome = n; }

        public String getNome() { return this.nome; }

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

        public boolean equals(Object o) {
            if (this==o) return true;
            if (o==null || this.getClass()!=o.getClass()) return false;
            Pessoa p = (Pessoa)o;
            return this.nome.equals(p.getNome());
        }
}

public class Carro extends Xpto {

    private String matricula;

    public Carro(String n) { this.matricula=n; }

    public String getMatricula() { return this.matricula; }

    public boolean equals(Object obj) {
        if (this==obj) return true;
        if (obj==null || this.getClass()!=obj.getClass()) return false;
        Carro c = (Carro)obj;
        return this.matricula.equals(c.getMatricula());
    }
}

public class Main {

    public static void foo(Xpto x1, Xpto x2) {
        System.out.println(x1.equals(x2));
    }

    public static void main(String[] args) {
        // TODO code application logic here
        Carro c1 = new Carro("ABC");
        Carro c2 = new Carro("DEF");
        Pessoa p1 = new Pessoa("Manel");
        Pessoa p2 = new Pessoa("Manel");
        foo(c1,c2);
        foo(p2,p2);
    }

}

//Output

false
true

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
M6

Baderous, concordo contigo. O que dizes é o que eu afirmo na minha solução 1.


10 REM Generation 48K!
20 INPUT "URL:", A$
30 IF A$(1 TO 4) = "HTTP" THEN PRINT "400 Bad Request": GOTO 50
40 PRINT "404 Not Found"
50 PRINT "./M6 @ Portugal a Programar."

 

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
Baderous

Baderous, concordo contigo. O que dizes é o que eu afirmo na minha solução 1.

Ah ok, não me tinha apercebido.

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites

Crie uma conta ou ligue-se para comentar

Só membros podem comentar

Criar nova conta

Registe para ter uma conta na nossa comunidade. É fácil!

Registar nova conta

Entra

Já tem conta? Inicie sessão aqui.

Entrar Agora

×

Aviso Sobre Cookies

Ao usar este site você aceita os nossos Termos de Uso e Política de Privacidade. Este site usa cookies para disponibilizar funcionalidades personalizadas. Para mais informações visite esta página.