在java中的动态绑定和构造函数链接之间混淆

时间:2017-10-28 20:26:19

标签: java inheritance constructor binding polymorphism

根据我正在阅读的书,下面的代码打印出来:

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个月的大学新生,他是一个小课程)。那么有人可以解释我的错误吗?

1 个答案:

答案 0 :(得分:0)

调用哪个方法不依赖于构造函数执行。 然而,有一个技巧,父的构造函数作为子构造函数的第一步执行。它将由编译器添加,除非您明确添加它。例如。学生的构造函数如下所示:

public Student() {
  super(); //parent initialised before child
}

你实际做的是一种覆盖方法。

您可以考虑替换任何父类中的方法。 另外要理解这一点你可以想到继承链: 毕业生 - >学生 - >人 - >对象

将调用链中找到的第一个toString方法。实际上这个版本用于原型继承,在java中它的实现方式不同。但是为了理解它应该就足够了。

关于你的例子:

  • 您没有覆盖父学生课程的父方法,因此学生的方法被称为
  • 学生覆盖Person toString方法,学生的方法称为
  • Person覆盖Object的toString方法,Person的方法称为
  • 调用Object的toString,因为它没有Parent类,并且包含toString方法。

您可以在互联网上阅读有关方法覆盖的更多信息:)