我有2个重载方法,一个运行超类,另一个运行子类。我希望在发送子类时,java会知道运行特定于子类的方法。唉,它运行的是超类之一。这是一个例子:
public class Test {
static class SuperClass {}
static class SubClass extends SuperClass {}
static void stuff(SuperClass superclass) {
System.out.println("IN 1");
}
static void stuff(SubClass subClass) {
System.out.println("IN 2");
}
public static void main(String[] args) {
SuperClass aClass = new SubClass() ;
stuff(aClass) ;
}
}
我希望打印“IN 2”,但我会得到“IN 1”
所以我有2个问题: 1.为什么会这样 2.我如何实现我想要的结果?
提前致谢
答案 0 :(得分:10)
为什么会这样?
因为重载解析发生在编译时,而aClass
变量的编译时类型是SuperClass
我如何实现我想要的结果?
将aClass
的编译时类型更改为SubClass
:
SubClass aClass = new SubClass();
或者在方法调用中强制转换:
stuff((SubClass) aClass);
如果您希望实际能够处理任何SuperClass
,您应该查看覆盖而不是重载,或者visitor pattern / double dispatch。
答案 1 :(得分:2)
通过将aClass声明为SubClass的实例
SuperClass aClass = new SubClass() ;
即使您将其实例化为SubClass,也可以将其声明为SuperClass。将该行更改为:
SubClass aClass = new SubClass() ;
再试一次。
答案 2 :(得分:1)
就像Skeet先生所说,它正在发生,因为aClass
变量的编译时类型是SuperClass
。以下是使用interface和instanceof
public class Legit {
public static interface Animal {}
public static abstract class Mammal implements Animal {}
public static class Lion extends Mammal {}
public static class Cow extends Mammal {}
public static abstract class Reptile implements Animal {}
public static class Snake extends Reptile {}
public static void doSomething(Animal animal) {
if (animal instanceof Lion) {
System.out.println("RAAWWRR!");
} else if (animal instanceof Cow) {
System.out.println("MOOO!");
} else if (animal instanceof Reptile) {
System.out.println("HISSSSS!");
}
}
public static void main (String ... args) {
Animal animal1 = new Lion();
Animal animal2 = new Cow();
Animal animal3 = new Snake();
doSomething(animal1);
doSomething(animal2);
doSomething(animal3);
}
}
输出:
RAAWWRR!
MOOO!
HISSSSS!