class Monster {
boolean frighten(int x) {
System.out.println("Monster");
return true;
}
}
class Vampire extends Monster {
boolean frighten(byte x) {
System.out.println("Vampire");
return true;
}
}
class Dragon extends Monster {
boolean frighten(int x) {
System.out.println("Dragon");
return true;
}
}
class Sample {
public static void main(String s[]) {
Monster[] inst = new Monster[3];
inst[0] = new Monster();
inst[1] = new Vampire();
inst[2] = new Dragon();
for (int i = 0; i < 3; i++) {
inst[i].frighten(i);
}
}
}
当我在x
或int
类中使用Monster
作为Dragon
运行上述代码时,代码可以正常工作。但是,当我通过在x
或int
类中将long
的类型从Monster
更改为Dragon
来运行代码时,会打印以下内容:< / p>
Monster
Monster
Monster
有人可以解释输出背后的逻辑吗?
答案 0 :(得分:8)
您没有将<form id="myForm">
<input type="checkbox" name="somename" id="first" />
<input type="checkbox" name="somename" id="second" />
<input type="checkbox" name="somename" id="third" />
</form>
$('checkbox[name=somename"]').each(function () {
if ($(this).prop("checked") == true) {
alert("I'm checked!");
}
});
传递给byte
的实例;你带着你的循环传递Vampire
。因为int
接受了Monster
,所以它就是所谓的。
实际上,你重载你的方法,而不是覆盖它 - 你有一个同名的方法和两个相同的签名。
在覆盖方法时,你真的应该使用同类型,这样你就不会遇到这样的问题。有效地:更改int
中frighten
的签名以接受Vampire
而不是int
。
使用byte
注释您的方法将让编译器帮助选择这样的东西。
@Override
答案 1 :(得分:2)
如果您想要覆盖,可以使用注释。然后编译器将帮助您发现此类错误。例如,编译器会发现此处存在错误。
class Vampire extends Monster
{
@Override
boolean frighten(byte x)
{
System.out.println("Vampire");
return true;
}
}
答案 2 :(得分:0)
写作时
b = [i[:] for i in a]
因为inst[i].frighten(i);
的类型为inst[i]
,所以编译器必须在Monster
类上找到与参数匹配的frighten
方法 - 就实际代码而言在这里,它是Monster
。
它在您传递的所有frighten(int)
实例上调用此方法 - 无论该类在运行时是什么,在编译时选择该方法。
这意味着永远不会调用Monster
方法 - 它是重载,而不是覆盖,因为签名{{1} }和Vampire.frighten(byte)
不匹配。
如果在frighten(int)
上将frighten(byte)
方法的参数更改为frighten
,则编译器只能从long
上定义的方法中选择,因此它是唯一知道的方法它可以安全地在所有实例上调用Monster
:子类都不会覆盖此方法 - 因此行为是基类的行为。
如果在Monster
上将frighten(long)
方法的参数更改为frighten
,则它不再覆盖基类中的方法 - 因此行为是基类的行为。
停止此“意外”行为的方法是始终将@Override添加到您认为覆盖基类中的方法的方法中。如果带有该注释的方法实际上没有覆盖基类上的方法,编译器会抱怨。