Jump to content
  • Revista PROGRAMAR: Já está disponível a edição #60 da revista programar. Faz já o download aqui!

Sign in to follow this  
msr

Abstract class, equals() e subclasses

Recommended Posts

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);
}
}

Share this post


Link to post
Share on other 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."

 

Share this post


Link to post
Share on other 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

Share this post


Link to post
Share on other 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."

 

Share this post


Link to post
Share on other sites
Baderous

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

Ah ok, não me tinha apercebido.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  

×

Important Information

By using this site you accept our Terms of Use and Privacy Policy. We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.