父进程中的方法如何调用子进程中的方法?

时间:2016-05-11 16:36:03

标签: java inheritance polymorphism

我有父母和子女。

父类有两个孩子覆盖的方法。

以下是一个例子:

public class May11 extends May11Parent
{
    public void m1()
    {
        super.m1();
        System.out.println("3");
    }

    public void m2()
    {
        super.m2();
        System.out.println("4");
    }

}

public class May11Parent
{
    public void m1()
    {
        System.out.println("1");
        m2();
    }

    public void m2()
    {
        System.out.println("2");
    }

}

然后我有一个带有父对象引用的子对象(子类中的主要方法)。我执行m1(),我知道这是m1()的孩子的身体。孩子打电话给父母。家长致电m2()。神奇地执行了子和父的两个m2()方法。

我的想法是,将被解雇的父母m2()。如果它不是父母那么孩子!

我认为这可能与多态有关,但我甚至尝试了一个带有子引用的子对象,但事情是一样的。我无法理解发生了什么。任何想法??

这是一个很好的截图:

Parent-Child weirdness

3 个答案:

答案 0 :(得分:1)

这里没有魔力。

首先:

引用该对象的变量的类型仅限制哪些方法是"可见"在那个地方。实现仍由引用的对象实例决定。

(想象一下你的子类(May11)正在指定一个额外的m3()方法。从具有父类类型(May11Parent)的变量中,这将不可调用。)

第二

可以从代码中轻松确定呼叫序列:

最初,假设您的对象引用绑定到变量var
(类型May11或类型May11Parent

  1. 致电var.m1()
    这会调用May11.m1(),因为对象实例是May11类。
  2. m1()正在呼叫super.m1()
    这将执行May11Parent.m1()
  3. May11Parent.m1()正在打印" 1 "
  4. May11Parent.m1()致电m2()
    由于对象实例是May11类型,因此执行May11.m2()
  5. May11.m2()正在调用super.m2()(这是May11Parent.m2()
  6. May11Parent.m2()正在打印" 2 "
  7. 返回May11.m2()下一个声明正在打印" 4 "
  8. 返回May11Parent.m1()这是
  9. 返回May11.m1()下一个声明正在打印" 3 "
  10. 所有这些都源于应用解决重载方法的规则。

答案 1 :(得分:1)

这称为运行时多态动态方法调度,在Java The Complete Reference(第9版,第178页)中说:

  

当通过超类引用调用重写方法时,Java根据调用发生时引用的对象类型确定要执行该方法的哪个版本。

在你的例子中(我想这是令人困惑的部分):

using // (Various)

namespace AspDotNetStorefront
{
    public partial class OrderManagerPage : SkinBase
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            // Here I get data from the SQL database.
            // Then,

            StringBuilder phoneOrdersHtml = new StringBuilder();
            // Build a series of HTML table rows with the data retrieved.
            // Finally,
            ltTableData.Text = phoneOrdersHtml.ToString();
        }

        void btnSaveAndEmail_Click(object sender, EventArgs e)
        {
            // Takes values from PhoneUpdates TextBox and creates SQL update query, then executes it.
            // If errors are returned, places them into ltErrors.Text.
        }
    }
}

public class May11Parent { public void m1() { System.out.println("1"); m2(); } // ... 内调用m2() Java将根据您在运行时 的对象类型决定调用哪种方法,由于m1()x的一种类型,因此将调用子类的May11

如果你知道这一点,那么你最终会得到你的输出:m2()

答案 2 :(得分:-3)

这是由于多态性造成的,如果不清楚一步一步发生了什么我建议你使用带有Toogle Breakpoint的调试器 我不知道你正在使用哪个IDE,但你的确有这个选择。 我使用Eclipse,在Eclipse中的工作原理如下: 右键单击要逐步执行的行,然后单击“Toogle Breakpoint” 然后点击“Degub As” - > “Java应用程序” 在屏幕顶部,黄色箭头将变为启用状态,并具有“步入”功能 点击它,你可以一步一步地按照你的程序做什么,我发现它非常有用,可以帮助你更好地理解代码中发生的事情。