关于压倒一切的原则

时间:2012-05-05 07:37:19

标签: java override

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

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();    
    }
}

现在我的问题;可以获得变量" i"父类A的方法,但我得到的方法也是A类。它是否获得了B类的方法,因为它覆盖了A类的方法?

3 个答案:

答案 0 :(得分: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()的正确版本。这被称为“动态绑定”或“后期绑定”:直到您的程序在运行时执行某些操作才能确定方法的正确版本。在Java中,大多数继承用法都涉及动态绑定。

答案 1 :(得分:0)

是的,它调用了B m1的实现。运行此代码时,将打印

I am in class B

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

答案 2 :(得分:0)

Yes it will invoke B's version of method,因为对象属于B类