2

可能重复:
具有继承接口的 Java 重载方法

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

我正在尝试像这样重载 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(Dog d) 方法,即使动物是狗。我使用这种方法是因为类 Foo 覆盖了 AnimalHelper 的 helpAnAnimal 方法。

我在这里错过了什么吗?我希望我不必检查 instanceof 然后强制转换它。我相信这在 .Net 中是开箱即用的,但是记忆有点褪色并且可能不正确。

4

4 回答 4

2

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

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

或者使用访问者模式

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) {
    }
}
于 2012-12-19T20:45:29.847 回答
1

你不能这样做,因为 Java 在编译时将它们都视为动物。

您可以做的是添加特定于实际 Dog 类的 Animal / 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);
    }
}

我不是兽医。

于 2012-12-19T20:43:56.477 回答
1

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

请注意,您已将私有方法用于这些方法,并且您将无法在此类之外使用这些方法。

于 2012-12-19T20:48:55.867 回答
0

这里有几件事:

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

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

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

于 2012-12-19T20:48:37.200 回答