在Java
问题描述:
动态绑定和构造函数链之间的困惑按照书上的我下面,下面的代码打印:在Java
public class DynamicBindingDemo {
public static void main(String[] args) {
m(new graduateStudent());
m(new Student());
m(new Person());
m(new Object());
}
public static void m(Object x) {
System.out.println(x.toString());
}
}
class GraduateStudent extends Student {
}
class Student extends Person {
public String toString() {
return "Student";
}
}
class Person extends Object {
public String toString() {
return "Person";
}
}
打印:
学生
学生
人
有人可以帮我解释为什么吗?在这里,我如何跟踪代码:
因此,m(new graduateStudent())调用m(Object x)的多态调用时,x.toString()由GraduateStuent类而不是Object类调用,因为GraduateStuent是实际对象的类型。在可以在GraduateStudent类中调用x.toString()之前,编译器会在GS类中隐式创建一个无参数构造函数,因为没有它。但是,在调用此构造函数之前,首先会调用学生类构造函数,因为它是超类。学生构造函数是在学生类中创建的(因为它没有),但是在构造函数被调用之前,人类构造函数被调用,因为它是超类等等直到我们到达Object超类,并且它的字符串方法应该被调用。 ...
我很确定我在很多事情上是错的(我是一个2个月的大学新生,这是一个小课程)。那么有人可以解释我出错了吗?
答
调用哪个方法不依赖于构造函数的执行。 然而,有一个技巧,父的构造函数作为子构造函数的第一步执行。它将被编译器添加,除非明确添加。例如。学生的构造函数如下所示:
public Student() {
super(); //parent initialised before child
}
实际上你做的是重写方法。
您可以考虑覆盖任何父类中的方法。 另外要了解这一点,你可以想到继承链: 毕业生 - >学生 - >人 - >对象
在链中找到的第一个toString方法将被调用。实际上这个版本用于原型继承,在java中它的实现方式不同。但是为了理解它应该是足够的。
所以对于你例子:
- 你是不是覆盖父Student类的父类的方法使学生的方法被称为
- 学生覆盖人toString方法,学生的方法被称为
- 人覆盖对象的toString方法,人的方法被称为
- 对象的toString被调用,因为它没有父类,并且包含方法toString。
你可以阅读更多有关在互联网:)
方法重载你似乎完全混为一谈构造和动态绑定的想法。当你调用'toString()'(这是不必要的,顺便说一下,因为'println(Object)'会为你做),构造函数就完成了。您可以完全消除问题其余部分对构造函数的讨论。看看这是否足够简化它是有道理的。 – chrylis