根据我正在阅读的书,下面的代码打印出来:
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";
}
}
打印:
学生
学生
人
java.lang.Object@130c19b
有人可以帮我解释一下原因吗?我在这里跟踪代码:
所以m(new graduateStudent())调用对m(Object x)的多态调用,x.toString()由GraduateStuent类而不是Object类调用,因为GraduateStuent是对象的实际类型。在可以在GraduateStudent类中调用x.toString()之前,编译器会在GS类中隐式创建一个无参数构造函数,因为没有。但是,在调用此构造函数之前,首先调用student类构造函数,因为它是超类。学生构造函数是在学生类中创建的(因为它没有),但在调用构造函数之前,调用Persons构造函数,因为它是超类,依此类推,直到我们到达Object超类并且应该调用它的字符串方法。 ...
我很确定我在很多方面都错了(我是一个2个月的大学新生,他是一个小课程)。那么有人可以解释我的错误吗?
答案 0 :(得分:0)
调用哪个方法不依赖于构造函数执行。 然而,有一个技巧,父的构造函数作为子构造函数的第一步执行。它将由编译器添加,除非您明确添加它。例如。学生的构造函数如下所示:
public Student() {
super(); //parent initialised before child
}
你实际做的是一种覆盖方法。
您可以考虑替换任何父类中的方法。 另外要理解这一点你可以想到继承链: 毕业生 - >学生 - >人 - >对象
将调用链中找到的第一个toString方法。实际上这个版本用于原型继承,在java中它的实现方式不同。但是为了理解它应该就足够了。
关于你的例子:
您可以在互联网上阅读有关方法覆盖的更多信息:)