如何强制Java动态方法调用绑定

时间:2012-12-19 20:34:57

标签: java dynamic polymorphism

  

可能重复:
  Java Overload method with inherited interface

我不肯定我的头衔是正确的,但如果不是,我相信我会得到纠正。

我试图像这样重载helpIt方法:

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

问题是,即使动物是狗,也从不调用helpIt(狗d)方法。 我使用这种方法是因为Foo类覆盖了AnimalHelper的helpAnAnimal方法。

我在这里遗漏了什么吗?我希望我不必检查instanceof然后再投射它。 我认为这在.Net中开箱即用,但内存有点褪色,可能不正确。

4 个答案:

答案 0 :(得分:2)

使helpIt()方法成为Animal的可覆盖实例方法:

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

或使用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) {
    }
}

答案 1 :(得分:1)

你无法做到这一点,因为Java在编译时将它们全部视为动物。

您可以做的是将动物/狗特有的算法添加到实际的Dog类中,例如:

class Animal {

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

class Dog {

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

然后你可以在helpAnimal中调用这些特定的方法:

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

我不是兽医。

答案 2 :(得分:1)

您是否从同一类的方法中调用helpIt(Dog d)?

注意,您已使用private作为方法,并且您将无法在此类之外使用这些方法。

答案 3 :(得分:0)

这里有一些事情:

  • Java肯定不会调用helpIt(Dog d)方法,因为变量a的类型为Animal。您必须手动检查并调用正确的方法。这实际上是类型向下/向上铸造的情况。不确定.Net虽然。

  • Foo假设是什么?它是辅助类吗?如果是这样我就不会实现接口,我会删除构造函数并将私有方法公之于众。这样您就可以直接使用它们并避免手动转换。

  • 或者Java是一种面向对象的语言,因此如果helpItAnimal的行为,我会将方法移动到Animal类中并将助手类放在一起。