2
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()?

4

5 回答 5

5

您必须区分 的静态类型运行时类型。aObjaObj

代码如

A aObj = new B(); 

产生一个aObj具有静态类型A和运行时类型的变量B

在决定允许或不允许什么时,编译器只会费心查看静态类型。

对于您的问题:

1.为什么我无法通过 aObj 访问该变量,尽管它是指 B 类?

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

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

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

于 2012-05-15T07:00:15.773 回答
2

aObj是类型的局部变量AA没有被调用的成员b,那只是在你的子类B中。如果你想使用b,你需要声明一个 type 的变量B,但当然你只能分配它的实例B(或子类,如果有的话)。

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

于 2012-05-15T06:54:04.683 回答
1

这种行为被称为virtual method invocation,它是 Java 的一个重要方面polymorphism。你应该看看这个教程

于 2012-05-15T07:05:36.517 回答
0

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

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

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

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

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

即使 A 中没有 show() 方法,以下内容也可以使用。

aObj = new B();
aObj.show(); //calls B's show()
于 2012-05-15T07:03:32.660 回答
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,你仍然有一个里面没有变量b的对象。所以,尝试访问 b 会给你编译时错误。

  2. 在 show() 的情况下,A 和 B 都有这个方法,所以你在这里所做的实际上是在运行时覆盖它。这不过是多态性。因此,由于 A 已经有方法 show(),并且稍后被 B 覆盖,

A a = 新 B(); 一场表演();

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

于 2012-05-15T07:05:53.363 回答