这些父类和子类的解释?

时间:2013-07-26 10:26:45

标签: java inheritance

class BaseClass {
    int data = 101;
    public void print() {
        System.out.print(data + " ");
    }
    public void fun() {
        print();
    }
}

class SubClass extends BaseClass {
    int data = 202;
    public void print() {
        System.out.print(data + " ");
    } 
}

class TestClass {
    public static void main(String[] args) {
        BaseClass obj = new SubClass();
        obj.print();//call 1
        obj.fun();// call 2
        System.out.print(obj.data);//call2
    } 
}

所以我有一个父/子关系类和一个有call1,call2,call3的测试类。

  

1:关于call1,我的理由是,因为 print()被子类重写,函数调用将打印正确的数据变量。这似乎是正确的,因为这是正确的答案。

     

2:现在关于call2,因为fun只存在于父类中,所以调用会去那里,理想情况下应该调用父类的 fun 方法并输出数据父类的变量。根据子类的输出数据的答案,这不是正确的答案。

任何人都可以向我解释一下,我的推理有什么问题吗?

3 个答案:

答案 0 :(得分:4)

这是由于polymorphism。您覆盖子项中的print()方法,以便在子项调用fun()实例时使用print()方法的SubClass版本调用它。

由于实例是SubClass,它将使用它拥有的方法的版本而不是它的父版本。

可以找到有关JVM如何解析其方法的良好资源here

答案 1 :(得分:1)

  

现在关于call2,因为fun只存在于父类中,所以   电话将去那里,理想情况下应该调用有趣的方法   父类并输出父类的数据变量。这是   不正确答案,根据答案输出数据   孩子班。

这不正确。 fun()的{​​{1}}会调用BaseClass的{​​{1}},因为它会被覆盖。 运行时多态性适用于此处。

答案 2 :(得分:1)

   case 1 : obj.fun();

您已覆盖print();方法 在运行时,java根据对象类型解析方法调用。
所以在这里它首先在fun()中搜索方法SubClass,但是没有在那里找到方法,
因为你SubClass没有它(你没有被fun()覆盖),而且 然后它转到BaseClass(父)类并找到fun()方法。

然后有一个必须执行的方法print() 此处也遵循相同的步骤,首先在SubClass中搜索并找到print()
SubClass本身并执行它

所以这就是你得到的结果。

  case 2 :  System.out.println(obj.data)

此处data是变量,
编译器在解析对变量的访问时(以及在解决重载时)仅考虑声明的变量类型
此处声明的类型为BaseClass,因此结果为101

如果您创建这样的对象

   SubClass obj2 = new SubClass(); 
   System.out.println(obj2.data); 

然后结果将是202。因为声明的类型是'SubClass'。