Java – Understanding Java Dynamic Binding

arraybindingdynamicjavapolymorphism

I am having trouble understanding the OOP Polymorphic principl of Dynamic Binding ( Late Binding ) in Java. I looked for question pertaining to java, and wasn't sure if a overall answer to how dynamic binding works would pertain to Java Dynamic Binding, I wrote this question.

Given:

class Person
{
     private String name;

     Person(intitialName)
     {
          name = initialName;
     }

     // irrelevant methods is here.

     // Overides Objects method
     public void writeOutput()
     {
          println(name);
     }
}

class Student extends Person
{

     private int studentNumber;

     Student(String intitialName, int initialStudentNumber)
     {
     super(intitialName);
     studentNumber = initialStudentNumber;
     }

     // irrellevant methods here...

     // overides Person, Student and Objects method
     public void writeOutput()
     {
      super.writeOutput();
      println(studentNumber);
     }   
  }

class Undergaraduate extends Student
{

     private int level;

     Undergraduate(String intitialName, int initialStudentNumber,int initialLevel)
     {
     super(intitialName,initialStudentNumber);
     level = initialLevel;
     }

     // irrelevant methods is here.

     // overides Person, Student and Objects method
     public void writeOutput()
     {
      super.writeOutput();
      println(level);
     }

  }

I am wondering. if I had an array called person declared to contain objects of type Person:

  Person[] people = new Person[2];
  person[0] = new Undergraduate("Cotty, Manny",4910,1);
  person[1] = new Student("DeBanque, Robin", 8812);

Given that person[] is declared to be of type Person, you would expect, for example, in the third line where person[0] is initialized to a new Undergraduate object,to only gain the instance variable from Person and Persons Methods since doesn't the assignment to a new Undergraduate to it's ancestor denote the Undergraduate object to access Person – it's Ancestors, methods and isntance variables…

Thus …with the following code I would expect

  person[0].writeOutput();  // calls Undergraduate::writeOutput()
  person[1].writeOutput();  // calls Student::writeOutput() 

person[0] to not have Undergraduate's writeOutput() overidden method, nor have person[1] to have Student's overidden method – writeOutput().

If I had

Person mikeJones = new Student("Who?,MikeJones",44,4);
mikeJones.writeOutput();

The Person::writeOutput() method would be called.

Why is this not so? Does it have to do with something I don't understand about relating to arrays? Does the declaration Person[] people = new Person[2] not bind the method like the previous code would?

Best Answer

It has nothing to do with arrays, it is the effect of the "late binding". The Java compiler only checks that Person has the writeOutput method, but does not bind the call to that class method. The binding is performed at runtime, where the JVM finds that Person[0] is an UnderGraduate and calls the method definition from UnderGraduate, and not the one from Person.

I understand that C++ works the other way unless you specify virtual, but it is better this way (if you think that a class encapsulates data and methods, you ensure that the methods used are the ones which really matter to the encapsulated data).

Related Topic