Method parameter with abstract class

1

Hello. I think my question 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 parameter of a method 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 it, without success:

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

Is there any way to do what I want?

Thank you!

    
asked by anonymous 24.04.2015 / 01:45

3 answers

1

Thinking only of Object Orientation, this is not possible.

The doSomething 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 Dog and not to Cat, so if your method receives Animal , get the Cat class, but try to call the bark () method, it would be "lost", so it is not possible to do what you want correctly.

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

Then your method would call Animal.Action () and each Animal implementation does what it has to do ...

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

You can do this as you said in the comments, using equals and converting the object, but you would break the Open / Closed principle, because with each new Animal implementation, you would have to add a new "if" in your doSomething method to handle only this new implementation.

    
24.04.2015 / 02:24
1

Friends, thank you very much for the contributions, which were very useful. I'm still new to Java and I'm skating on some concepts.

I ended up thinking a little more about the concept I was trying to use and I saw that it did not make much sense (in the sense of object orientation).

I have decided as follows: I created a "barkable" interface, implemented it in Dog, and set the constraint on the DoSomething () method for the interface, rather than the abstract class.

In code, this would be:

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

[] 's!

    
24.04.2015 / 03:40
0

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

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

A classic example of using equals() is for dates. If you create two dates, that is, two different objects, containing 10/31/1979, when comparing with the == will get false, because they are references to different objects. It would be correct, then, to rewrite this method by doing the attribute comparisons, and the user would invoke equals() rather than compare with ==.

You could create a method with another name instead of rewriting equals that receives 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

    
24.04.2015 / 02:24