我不肯定我的头衔是正确的,但如果不是,我相信我会得到纠正。
我试图像这样重载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中开箱即用,但内存有点褪色,可能不正确。
答案 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是一种面向对象的语言,因此如果helpIt
是Animal
的行为,我会将方法移动到Animal类中并将助手类放在一起。