Java继承问题 - 尝试理解这个概念

时间:2014-01-30 12:03:48

标签: java inheritance

我试着理解继承概念,我有一个小问题。

我有两个A和B类:

public class B extends A
{
    public B()
    {
        System.out.println ("B");
    }

    public void arik ()
    {
        System.out.println("Arik_B");
    }
    public void yosef ()
    {
        System.out.println ("Yosef");
    }

    public void superYosef()
    {
        super.yosef();
    }
}

public class A
{
    public A()
    {
        System.out.println ("A");
    }

    public void arik ()
    {
        System.out.println ("Arik_A");
    }

    public void yosef ()
    {
        arik();
    }
}

主:

A ab = new B();
((B) ab).superYosef();

A ab = new B();将打印A B,这很清楚。 但是行((B) ab).superYosef();打印Arik_B并且我不明白为什么。 在运行ab之前输入A并在运行它时B需要打印Yosef

4 个答案:

答案 0 :(得分:5)

this上调用实例方法时,唯一重要的是调用它的对象的类型。此类型仅在运行时中已知。

super上调用实例方法时,动态调度不适用。该方法在编译时选择。

在您的代码中:

  1. 您创建了new B();并致电B.superYosef();
  2. 该方法中出现的来电super.yosef();会静态调用A.yosef() (不受动态调度影响);
  3. A.yosef()调用this.arik() - 与上述不同,调用this的方法受动态调度影响;
  4. this的类型为B,因此调用方法B.yosef()

答案 1 :(得分:5)

当你这样做时

A ab = new B();

然后是ab类型的变量A,但它引用的实际对象是B类型。对象的实际类型决定了将调用哪个方法,而不是变量的类型。

因此,当您在ab上调用已在类B中重写的任何方法时,将调用类B中的版本。

让我们看看这里发生了什么:

((B) ab).superYosef();

您需要强制转换,因为方法superYosef仅在类B中定义。

该方法调用super.yosef();,它将调用类yosef中的A方法。 A.yosef调用arik,并在类B中覆盖此方法。请注意,我们在一个实际为B的对象上调用了该方法,因此调用arik中的B方法,打印Arik_B

答案 2 :(得分:3)

调用方法时:

((B) ab).superYosef();

ab引用引用的实际实例仅属于类B。进一步说,此调用将调用类superYosef()中的方法B方法。现在,我们来看看那个方法:

public void superYosef()
{
    super.yosef();
}

这将调用类yosef()中的A方法。由于super。该实例仍为B。然后在yosef()方法中:

public void yosef ()
{
    arik();  // equivalent to `this.arik();`
}

在这里,您可以参考this持有对类B实例的引用。您调用arik(),它在类B中被覆盖,因此调用类arik()的方法B。唯一重要的是,实际对象的类型为B

答案 3 :(得分:0)

因为您使用类B覆盖方法arik,所以这就是它在B类中访问此方法的原因。

您的ab变量仍为B