Method parameter with abstract class

Asked

Viewed 825 times

1

Hello. I believe my doubt is very simple, but I really did not find any solution, after much research.

In Java, I have two concrete classes that extend an abstract class, as the example:

public class Animal {}
public class Dog extends Animal {
    public void bark() {}
    public void eat() {}
}
public class Cat extends Animal {
    public void eat() {}
}

Only the Dog class has the bark method().

I would like a method parameter to accept any Animal object, so I did this:

public void doSomething(Animal animal) {}

But I need this method to make the animal bark if it’s a dog, so I tried this, unsuccessfully:

public void doSomething(Animal animal) {
    animal.bark();
}

Is there any way I can do what I want?

Thank you!

  • I believe that creating an Equal() method for your animal, and if Animal.What(Dog) == true, barking will work.

  • http://javafree.uol.com.br/topic-3932-Comparar-variaveis--ou-equals.html

3 answers

1

Thinking only about Object Orientation, this is not possible.

The Mething method receives the Animal class, so this method has to know what to do with this type of class, the bark() method, belongs only to the Dog and not to the Cat, so if your method that receives Animal, receive the Cat class, but try to call the bark() method, it would stay "lost", therefore, it is not possible to do what you want correctly.

What you could have, is an "Acao" method for example, where in the Dog class you would implement the code that barks and in the Cat class you would implement the code that makes meow for example.

Ai your method would call animal. Acao() and each implementation of Animal does what it has to do...

If your method already knows that you will call the "bark()", then, in theory, you already know that you will receive a dog and not an Animal and then it does not make sense to receive an Animal as a parameter.

You can do what you want as stated in the comments, using equals and converting the object, however, you would break the Open/Closed principle, because with each new implementation of Animal, you would have to add an "if" new in your doSomething method to treat only this new implementation.

1

Friends, thank you so much for the contributions, which were very useful. I am still new to Java and I’m skating in some concepts.

I ended up thinking a little bit more about the concept I was trying to employ and saw that it didn’t make much sense (in the sense of object orientation).

I have resolved as follows: I created a "barkable" interface, implemented it in Dog and set the restriction in the doSomething() method for the interface, rather than the abstract class.

In code, that would be it:

interface Barkable() {
    public void bark();
}
public class Dog extends Animal implements Barkable {
    //...
}
public void doSomething(Barkable animal) {
    animal.bark();
}

[]'s!

0

Java alone does not compare attributes or objects, but there is a method in the Object class that can be rewritten to create this comparison criterion. That method is the equals().

The equals() receives an Object as argument and must verify that it is itself equal to the received Object to return an boolean. If you do not rewrite this method, the inherited behavior is to make a == with the object received as argument.

A classic example of the use of equals() is for dates. If you create two dates, that is, two different objects, containing 10/31/1979, when comparing with == you will receive false, as they are references to different objects. It would then be correct to rewrite this method by making comparisons of attributes, and the user would invoke equals() instead of comparing with ==.

You could create a method with another name instead of rewriting equals that gets Object, but it is important because many libraries call it through polymorphism.

Example:

public class Pessoa extends Object implements Serializable {  
   private int idade;  
   private String nome;  

   public Pessoa() {  
      setIdade(0);  
      setNome("Alguem");  
   }  

   public boolean equals(Pessoa p) {  
      boolean compare = false;  

      if ((this.nome.equals(p.getNome())) && (this.idade == p.getIdade())   )  
         compare = true;  

      return compare;  
   }  
}  

So far it’s the only way that comes to mind.

Source 1

Source 2

Source 3

Browser other questions tagged

You are not signed in. Login or sign up in order to post.