我有一个问题,下面是我的代码。
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类的方法?
答案 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)