有一个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).
这是怎么回事呢? 难道这样不是正确的重载? 那么应该怎么做才能实现我想要的结果?

解决方案 »

  1.   

    你的类D实现的f(A a)方法本来就是方法体置空,所以你的对象d就什么都不会作,和你传经来的A到底是什么根本就无关。也就是说,你得不到任何结果是意料中的事情,根本就跟类A和B无关。你看看清楚你自己的注释:public void f(A a) {} //因为类D也实现了接口I,所以肯定要给出f(A a)的实现,这里仅把它置空
      

  2.   

    凭什么要执行f(B b)呢?你的B类和A类本来就是不同的两个类。这个根本没有到重载!!!
    你自己也说了:
    对于public void f(B b)和public void f(A a)根本就是两个方法!!!!
      

  3.   

    A a=new B(); 所以是调用的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  里面有比较详细的介绍。
      

  4.   

    A a=new B(); 所以是调用的f(A a); 
    补充下吧:因为你这里不是使用a.方法()的调用,
    而a只是一个方法的参数。a的类型是A所以会走f(A a); 
      

  5.   

    但是f(B b)难道不是对f(A a)的一个重载吗? 既然是重载,执行时应该是晚绑定,按照参数类型选择最匹配的方法去执行喽
    B是A的子类,所以虽然现在传进去的a对象在声明时是声明成A类, 但实际指向一个B类对象的引用.  当执行f(a)时选择最匹配的方法,不就应该是f(B b)吗?
      

  6.   

    我晕~~~请问lz~A和B是相同的类吗?
      

  7.   

    D.f(B b)是对D.f(A a)的一个重载。和上面说的一样
    执行时应该是晚绑定那是对于调用D.f(B b)和D.f(A a)的调用者D,这个是多态的实现。
    但是对于参数是编译的时候绑定的。所以只会看引用的类型,不会看引用具体的指向的对象的类型
      

  8.   

    我再说清楚些,f(B b)是对f(A a)是重载,现在你就是用调用 d.f(a)来调用那当然就调用d的f(A a)方法了
    比如String类型中的:valueOf(boolean b)和String valueOf(char c) 如果你引入的参数是个boolean那当然就是使用第一个方法,而如果参数是char那就是第二个方法。lz你搞晕了多态和重载~~~
     
      

  9.   

    哦,有点明白了.参数虽说是父子类的关系但仍然是两个类,传入A的话最匹配的类型还是A,不会因为参数实际指向B类的对象而认为应该调用f(B)那么我现在想实现的效果就是,不管传入的A类对象具体是A的哪一个子类对象,都能让它自动去调用最匹配的方法,而不用写成这样的坏味道代码:
    void f(A a) {
      if (A instanceof SubA1) {...}
      else if (A instanceof SubA2) {...}
    ... ...
    应该用什么方式呢?
      

  10.   

    sorry,刚才说话没怎么考虑。可以实现一个方法
    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");
    }
    }
    希望有用