1

我有一个问题,下面是我的代码。

class A
{
    int i=10;
    public void m1() {
        System.out.println("I am in class A");
    }    
}

class B extends  A 
{    
    public void m1() { 
        System.out.println("I am in class B"); 
    }       
}

class main2 extends A 
{       
    public static void main(String...a) {
        A a1= new B();
        a1.m1();    
    }
}

现在我的问题;获取父类A的变量“i”是可以的,但是我获取的方法也是A类的。是不是获取了B类的方法,因为它覆盖了A类的方法?

4

3 回答 3

1

在 Java 中,任何派生类对象都可以分配给基类变量。例如,如果您有一个名为 A 的类,您从该类派生了 B 类,您可以这样做:

A a1 = new B();

左边的变量是 A 类型,而右边的对象是 B 类型。只要左边的变量是 B 的基类,就可以这样做。能够进行这样的赋值设置了所谓的“多态行为”:如果 B 类具有与 A 类中的方法相同的方法,则将调用 B 类中方法的版本。例如,如果两个类都定义了一个名为 m1() 的方法,并且您这样做:

a1.m1();

将调用 B 类中的 m1() 版本。即使您使用 A 变量类型来调用方法 m1(),也不会执行 A 类中的 m1() 版本。相反,它将被执行的是 B 类中的 m1() 版本。分配给 A 变量的对象的类型决定了调用的方法。

因此,当编译器扫描程序并看到如下语句时:

a1.m1();

它知道 a1 是 A 类型,但编译器也知道 a1 可以是对从 A 派生的任何类的引用。因此,编译器不知道该语句正在调用的 m1() 的版本。直到作业:

A a1 = new B();

执行以确定 m1() 的版本。由于分配直到运行时才发生,因此直到运行时才知道 m1() 的正确版本。这被称为“<strong>动态绑定”或“<strong>后期绑定”:直到您的程序在运行时执行某些操作,才能确定方法的正确版本。在 Java 中,继承的大多数使用都涉及动态绑定。

于 2012-05-05T07:56:07.110 回答
0

是的,它调用Bm1. 当您运行此代码时,它会打印

I am in class B

正如预期的那样。(请注意,您实际上并没有在您发布的任何代码中使用 i,所以我不确定第一部分是关于什么的......)

于 2012-05-05T07:39:40.113 回答
0

是的,它会调用 B 的方法版本,因为对象属于 B 类

于 2012-05-05T07:39:40.440 回答