2

Possible Duplicate:
Java Overload method with inherited interface

I'm not positive my title is correct, but I'm sure I'll be corrected if it's not.

I'm trying to overload the helpIt method like so:

class Animal{}
class Dog extends Animal{}

class Foo implements AnimalHelper
{
  @Override
  public void helpAnAnimal( Animal a )
  { 
    helpIt( a );
  }

  private void helpIt( Dog d )
  {}

  private void helpIt( Animal a )
  {}
}

The problem is this never calls the helpIt( Dog d ) method, even when the animal is a Dog. I used this approach because the class Foo overrides the AnimalHelper's helpAnAnimal method.

Am i missing something here? I would hope i don't have to check instanceof and then cast it. I believe this worked out of the box in .Net, but that memory is a bit faded and possibly incorrect.

Community
  • 1
  • 1
rediVider
  • 1,266
  • 2
  • 13
  • 30
  • At compile time, Java sees the Dog as an Animal (see: http://stackoverflow.com/questions/1601365/java-overload-method-with-inherited-interface). – sdasdadas Dec 19 '12 at 20:37
  • I think your question has already been answered here http://stackoverflow.com/questions/11110631/java-overloading-and-inheritance-rules – MatthiasLaug Dec 19 '12 at 20:44

4 Answers4

2

Make the helpIt() method an overridable instance method of Animal:

class Foo implements AnimalHelper {
    @Override
    helpAnAnimal(Animal a) { 
        a.helpIt();
    }
}

Or use the visitor pattern:

public interface AnimalVisitor {
    void visitDog(Dog d);
    void visitOther(Animal a);
}

public class Animal {
    public void accept(AnimalVisitor visitor) {
        visitor.acceptOther(this);
    }
}

public class Dog extends Animal {
    public void accept(AnimalVisitor visitor) {
        visitor.acceptDog(this);
    }
}

class Foo implements AnimalHelper {
    @Override
    helpAnAnimal(Animal a) { 
        a.accept(new AnimalVisitor() {
            public void visitDog(Dog d) {
                helpIt(d);
            }
            public void visitOther(Animal a) {
                helpIt(a);
            }
        });
    }

    private void helpIt(Dog d) {
    }

    private void helpIt(Animal a) {
    }
}
JB Nizet
  • 678,734
  • 91
  • 1,224
  • 1,255
  • Thanks. I never used it before, but I like the visitor pattern because it keeps the functionality where I want it and allows for multiple implementations. – rediVider Dec 19 '12 at 21:05
1

You cannot do that as Java sees them all as Animals at compile time.

What you can do is add the algorithms that are Animal / Dog specific to the actual Dog class, for example:

class Animal {

    protected boolean hasRabies() {
        return animal.name.equals("Tim");
    }
}

class Dog {

    @Override
    protected boolean hasRabies() {
        return false; // Apparently dogs can't have rabies?
    }
}

Then you can call these specific methods in the helpAnimal:

private void helpIt(Animal a) {
    if (a.hasRabies()) {
        a.setTreats(4000);
    } else {
        a.setTreats(3000);
    }
}

I am not a veterinarian.

sdasdadas
  • 23,917
  • 20
  • 63
  • 148
1

Are you calling the helpIt(Dog d) from a method of the same class?

Note, you have used private for the methods and you will not be able to use these methods outside this class.

Vishwas Shashidhar
  • 807
  • 2
  • 9
  • 23
0

A few of things here:

  • Java definitely won't call the helpIt(Dog d) method because the variable a is of type Animal. You'll have to manually check and call the correct method. This is really a case of type down/up casting. Not sure about .Net though.

  • What is Foo suppose to be? Is it a helper class? If so I wouldn't implement to an interface, I would drop the constructor and make the private methods public. This way you might be able to use them directly and avoid the manual casting.

  • Alternatively Java is an object oriented language and therefore if helpIt is behaviour of an Animal I would move the method into the Animal class and drop the helper class all together.

ramsinb
  • 1,985
  • 12
  • 17