我有父母和子女。
父类有两个孩子覆盖的方法。
以下是一个例子:
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()
。如果它不是父母那么孩子!
我认为这可能与多态有关,但我甚至尝试了一个带有子引用的子对象,但事情是一样的。我无法理解发生了什么。任何想法??
这是一个很好的截图:
答案 0 :(得分:1)
这里没有魔力。
首先:
引用该对象的变量的类型仅限制哪些方法是"可见"在那个地方。实现仍由引用的对象实例决定。
(想象一下你的子类(May11)正在指定一个额外的m3()
方法。从具有父类类型(May11Parent)的变量中,这将不可调用。)
第二
可以从代码中轻松确定呼叫序列:
最初,假设您的对象引用绑定到变量var
(类型May11
或类型May11Parent
)
var.m1()
May11.m1()
,因为对象实例是May11
类。m1()
正在呼叫super.m1()
May11Parent.m1()
May11Parent.m1()
正在打印" 1 " May11Parent.m1()
致电m2()
May11
类型,因此执行May11.m2()
May11.m2()
正在调用super.m2()
(这是May11Parent.m2()
)May11Parent.m2()
正在打印" 2 " May11.m2()
下一个声明正在打印" 4 " May11Parent.m1()
这是May11.m1()
下一个声明正在打印" 3 " 所有这些都源于应用解决重载方法的规则。
答案 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应用程序” 在屏幕顶部,黄色箭头将变为启用状态,并具有“步入”功能 点击它,你可以一步一步地按照你的程序做什么,我发现它非常有用,可以帮助你更好地理解代码中发生的事情。