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 anUnderGraduate
and calls the method definition fromUnderGraduate
, and not the one fromPerson
.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).