如果我的问题很愚蠢,请不要生气。)
我有一段代码:
public class LinkageTest {
public static class Parent {
public void test() {
System.out.println("parent::test");
}
}
public static class Child extends Parent {
public void test() {
System.out.println("child::test");
}
}
public static class Tester {
public void test(Parent obj) {
System.out.println("Testing parent...");
obj.test();
}
public void test(Child obj) {
System.out.println("Testing child...");
obj.test();
}
}
public static void main(String[] args) {
Parent obj = new Child();
Tester t = new Tester();
t.test(obj);
}
}
当我运行它时,会打印下一个字符串:
Testing parent... child::test
如果我们有test
的实例,我无法理解为什么调用Parent
Child
方法?有人可以帮我吗?
答案 0 :(得分:3)
1)类Child
重新定义(覆盖)test
方法。 (多态性)
2)在Tester
课程中,test(Parent obj)
和test(Child obj)
方法已超载。调用方法时,将选择具有相应类型的方法。
3)在t.test(obj)
时,变量obj
具有明确定义的Parent
类型,因此将选择适当的方法并且"测试父级...& #34;打印。
4)在obj.test()
时,将调用Child
类的测试方法,因为这是一个多态性
答案 1 :(得分:1)
您正在通过父引用创建儿童的对象,例如
Parent obj = new Child(); // obj has Child and Parent both type
System.out.println(obj instanceof Parent); // it returns true
和孩子重写父母的测试方法,
public static class Child extends Parent{
public void test(){ //overriding here
System.out.println("child::test");
}
}
当您调用 t.test(obj)方法
时 public static void main(String[] args){
Parent obj = new Child();
Tester t = new Tester();
t.test(obj); // obj created by Parent reference
}
所以赶上:
public void test(Parent obj){ // catches here
System.out.println("Testing parent..."); // Here is your first output
obj.test();
}
然后obj有重写的测试方法,所以它调用
public static class Child extends Parent{
public void test(){ // overridden method first priority
System.out.println("child::test"); // Here is your second output
}
}
如果更改Child类测试方法名称,则调用Parent类测试方法,输出将为
Testing parent...
parent::test
答案 2 :(得分:1)
因为你打电话
Parent obj = new Child();
t.test(obj); //object created by Parent reference
此obj来自 parent ,因此它将从Tester类调用“Testing parent”。
然后,感谢多态,它也会从Child类调用“child :: test”,因为它被覆盖了。
尝试致电:
Child obj = new Child();
t.test(obj);
你会看到:
"Testing child..."
"child::test"
您还应该将@Override放在Child类的test()方法上。
答案 3 :(得分:0)
那是因为您正在使用参数类型Parent调用测试器方法。但实际对象里面,具体实现的是Child。这些可能不是描述它的好词,希望你理解。
如果您已调用typeof(obj),则会返回Parent。如果您已经调试了应用程序,那么您会看到调用的方法是带有Parent参数的方法,因为您传递的类型为Parent的参数。
更具体的对象是Child(实际上你可以施放obj Child并且它可以正常工作,因为它是内部的孩子)。当你做obj.test()时,它会调用child的方法,因为它被子项覆盖。
答案 4 :(得分:0)
致电Tester.test(Parent obj)
的决定是在编译时进行的。在编译期间,编译器必须选择方法签名(不是实现,而是签名)。编译器看到两个具有相同名称但签名不同的方法,它只能选择Parent
签名,因为您已声明Parent obj
。这就是为什么在最后的字节代码中它将呈现为
find method test(Parent) in object t and execute it
致电Child.test
的决定是在运行时进行的。在编译期间,编译器只找到一个方法测试签名(尽管在Parent / Child中有两个不同的实现,签名是相同的)。因此, Tester 类中两种方法的实际实现将是:
find method test() in object obj and execute it
所以,尽管调用了Tester.test(Parent)方法,它仍然会尝试在传递的对象中找到方法测试,一旦你传递了子 - 孩子的版本将被实际执行。< / p>