java中的动态方法调度

时间:2012-05-15 06:49:59

标签: java inheritance casting

class A{
int a=10;   
public void show(){ 
    System.out.println("Show A: "+a);
    }
}

class B extends A{
public int b=20;    
public void show(){
    System.out.println("Show B: "+b);
    }
}



public class DynamicMethodDispatch {

    public static void main(String[] args) {

    A aObj = new A();       
    aObj.show();    //output - 10

    B bObj = new B();
    bObj.show();   //output - 20

    aObj = bObj;   //assigning the B obj to A..         
    aObj.show();  //output - 20 

    aObj = new B();
    aObj.show();  //output - 20
             System.out.println(bObj.b);  //output - 20 
    //System.out.println(aObj.b); //It is giving error



     }
}

在上面的程序中,我在尝试调用 aObj.b 时遇到错误。
                1.为什么我不能通过aObj获取该变量,尽管它指的是B类?                  2.为什么我能够访问方法show()?

5 个答案:

答案 0 :(得分:5)

您必须区分aObj静态类型aObj运行时类型

代码如

A aObj = new B(); 

会生成aObj变量,其中包含静态类型A和运行时类型B

在决定允许和不允许的内容时,编译器只会费心查看静态类型

问题:

  

1.为什么我不能通过aObj访问该变量,虽然它是指B类?

因为(通常)编译器无法知道 aObj在运行时将引用B对象,所以只会引用某些对象A对象的形式。由于.b并非在所有A个对象上都可用,因此编译器会认为“比对不起更安全”并禁止它。

  

2.为什么我能够访问方法show()?

因为此方法 在所有A个对象中都可用(如果它未在子类中声明,它仍然继承自A)。

答案 1 :(得分:2)

aObjA类型的局部变量。 A没有名为b的成员,仅在您的子类B中。如果要使用b,则需要声明类型为B的变量,但当然只能为B(或子类,如果有的话)分配实例。< / p>

A声明了方法show(),但您覆盖了子类B中的实现。

答案 2 :(得分:1)

此行为称为virtual method invocation,它是Java中polymorphism的一个重要方面。你应该看看这个tutorial

答案 3 :(得分:0)

方法和字段具有不同的多态行为。

将被调用的方法是实例的运行时类型的方法

aObj=new B(); //new B()

将被调用的字段是您声明的引用类型的字段

A aObj = new A(); // A aObj

即使A中没有show()方法,以下内容仍然有效。

aObj = new B();
aObj.show(); //calls B's show()

答案 4 :(得分:0)

class A{ // class A has variable a and method show();
int a=10;   
public void show(){ 
    System.out.println("Show A: "+a);
    }
}

class B extends A{ //class B inherits variables and methods of A.
   // so class B has variable a, b and show(). Also, show is overridden by class B.
public int b=20;    
public void show(){
    System.out.println("Show B: "+b);
    }
}
  1. 因为A里面没有变量b,即使你将B传递给A,你仍然有一个A对象里面没有变量b。因此,尝试访问b将导致编译时错误。

  2. 在show()的情况下,A和B都有这个方法,所以你在这里做的实际上是在运行时覆盖它。这只不过是Polymorphism。因为A已经有方法show(),后来被B覆盖,

  3. a a = new B(); a.show();

    这将在运行时运行B的show()方法。