简体   繁体   中英

Binding of Variables at Compile Time and Runtime

I am trying to execute the following code to clear the concept of method binding at Runtime.I have three classes Employee.java , Programmer.java ,and JPolymorphism.java . I am trying to print the methods from employee and Programmer class.In method compilation is at runtime. By this way Programmer should be printed by the programmer.name but its printing Employee

Employee.java

package jpolymorphism;
class Employee {
    String name = "Employee";

    void printName() {
        System.out.println(name);
    }
}

Programmer.java

package jpolymorphism;
class Programmer extends Employee {
    String name = "Programmer";

    void print() {
        System.out.println(name);
    }

}

Test Clas

package jpolymorphism;
class JPolymorphism {
    public static void main(String[] args) {
        // TODO code application logic here
        Employee emp = new Employee();
        System.out.println(emp.name);
        Employee programmer = new Programmer();
        System.out.println(programmer.name);
        emp.printName();
        //The below code line shoul print Prograamer at run time 
        //but my code is prininting Employee Instead of Programmer
        programmer.printName();
    }
}

I am unable to understand Where is the error? As methods are binding at runtime and my last line of code programmer.name is of Programmer type and referance type is of employee type then according to the concept the line should pring Prograamer but it is also printing Employee.Where am i doing the mistake?

Employee emp = new Employee();
System.out.println(emp.name);

That prints Employee , obviously.

Employee programmer = new Programmer();
System.out.println(programmer.name);

That prints Employee , because field binding happens at compile-time, so programmer.name refers to the Employee.name field, since programmer is declared as Employee .

emp.printName();

That prints Employee , obviously.

programmer.printName();

That prints Employee , because you're calling the Employee.printName() method, which accesses the Employee.name field, and the method has not been overridden by subclass Programmer .

Why wasn't it overridden? Because the Programmer method is named print , not printName . If you had added the @Override annotation, as you should if you intended the method to override a superclass method, then the compiler would have told you that you had a problem.

If you rename the Programmer method to printName :

  • A good IDE would tell you to add the @Override annotation.

  • The programmer.printName() call will print Programmer .

The problem with the code is that when you are calling programmer.printName(); , it is calling the printName() function of the Employee class for which the variable is name whose value is "Employee".

The thing is that even though Programmer is a subclass of Employee , the variable name of the Programmer class is not accessible to Employee class. In inheritance, properties are inherited from the superclass, in this case, Employee but Employee cannot access the fields of its subclasses directly. So, when the programmer.printName(); invocation is done, the printName() method of the Employee class gets called and the value "Employee" gets printed.

As such the code does not reflect the concept of method binding at runtime as there is no override of a function as pointed out in the other answer .

This is because of the super() method. If you do not call the super() method from the child class's constructor, JAVA automatically calls the super class's constructor implicitly. The constructors of the parent classes are called, all the way up the class hierarchy through Object.

From the docs:

With super(), the superclass no-argument constructor is called. With super(parameter list), the superclass constructor with a matching parameter list is called.

Note: If a constructor does not explicitly invoke a superclass constructor, the Java compiler automatically inserts a call to the no-argument constructor of the superclass. If the super class does not have a no-argument constructor, you will get a compile-time error. Object does have such a constructor, so if Object is the only superclass, there is no problem.

If a subclass constructor invokes a constructor of its superclass, either explicitly or implicitly, you might think that there will be a whole chain of constructors called, all the way back to the constructor of Object. In fact, this is the case. It is called constructor chaining, and you need to be aware of it when there is a long line of class descent.

I hope this clears the confusion.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM