有一个interface I,定义了一个以抽象类A的对象(当然只能是其实际的子类的对象)为参数的方法f :
public interface I {
public abstract void f(A a);
}public abstract class A {...}类B是类A的非抽象子类:
public class B extends A {...}抽象类C实现了接口I,因此它也有一个方法f,但仍不实现它:
public abstract class C implements I {
//... ...
public abstract void f(A a);//或不写这句也可因为C还是抽象类
//... ...
}类D是一个类C的实际子类, 它是这样的:
public class D extends C {
//... ...
public void f(B b) {
//... ...
}
public void f(A a) {} //因为类D也实现了接口I,所以肯定要给出f(A a)的实现,这里仅把它置空
}在主程序里,有一个引用,它的类型被声明为A,然后对它赋了一个B类对象的引用; 另有一个D类的对象:
//... ...
A a=new B();
//... ...
D d=new D();
//... ...我期望的效果是这样: 调用 d.f(a),应该执行的是被重载的f(B b)吧? 但实际执行发现,执行的仍是被置空的f(A a).
这是怎么回事呢? 难道这样不是正确的重载? 那么应该怎么做才能实现我想要的结果?
public interface I {
public abstract void f(A a);
}public abstract class A {...}类B是类A的非抽象子类:
public class B extends A {...}抽象类C实现了接口I,因此它也有一个方法f,但仍不实现它:
public abstract class C implements I {
//... ...
public abstract void f(A a);//或不写这句也可因为C还是抽象类
//... ...
}类D是一个类C的实际子类, 它是这样的:
public class D extends C {
//... ...
public void f(B b) {
//... ...
}
public void f(A a) {} //因为类D也实现了接口I,所以肯定要给出f(A a)的实现,这里仅把它置空
}在主程序里,有一个引用,它的类型被声明为A,然后对它赋了一个B类对象的引用; 另有一个D类的对象:
//... ...
A a=new B();
//... ...
D d=new D();
//... ...我期望的效果是这样: 调用 d.f(a),应该执行的是被重载的f(B b)吧? 但实际执行发现,执行的仍是被置空的f(A a).
这是怎么回事呢? 难道这样不是正确的重载? 那么应该怎么做才能实现我想要的结果?
}
你自己也说了:
对于public void f(B b)和public void f(A a)根本就是两个方法!!!!
这个问题基本上是个双多态的问题。
如果你想调用f(B b)
可以考虑
public void f(A a) {}
if(a instanceof B)
{
this.f((B)a);
}else{
原来的f(A a);
}
} 目前看过的书中,双多态的问题在 Inside the C++ Object Model 里面有比较详细的介绍。
补充下吧:因为你这里不是使用a.方法()的调用,
而a只是一个方法的参数。a的类型是A所以会走f(A a);
B是A的子类,所以虽然现在传进去的a对象在声明时是声明成A类, 但实际指向一个B类对象的引用. 当执行f(a)时选择最匹配的方法,不就应该是f(B b)吗?
执行时应该是晚绑定那是对于调用D.f(B b)和D.f(A a)的调用者D,这个是多态的实现。
但是对于参数是编译的时候绑定的。所以只会看引用的类型,不会看引用具体的指向的对象的类型
比如String类型中的:valueOf(boolean b)和String valueOf(char c) 如果你引入的参数是个boolean那当然就是使用第一个方法,而如果参数是char那就是第二个方法。lz你搞晕了多态和重载~~~
void f(A a) {
if (A instanceof SubA1) {...}
else if (A instanceof SubA2) {...}
... ...
应该用什么方式呢?
D.f(Object o)
然后把本来的D.f(A a)方法改成D.fforA(A a)。然后用反射做,写了个简单的例子如下:
package squall.test;import java.lang.reflect.Method;class A
{
}class B extends A
{
}public class Test
{
public static void main(String[] args) throws Exception
{
A a = new B();
Test test = new Test();
test.f(a);
}
public void f(Object o) throws Exception
{
Class class1 = o.getClass();
String str = "ffor" + class1.getSimpleName();
Method method = this.getClass().getMethod(str, class1);
method.invoke(this, o);
}
public void fforA(A a)
{
System.out.println("a invoke");
}
public void fforB(B b)
{
System.out.println("b invoke");
}
}
希望有用