在编译时和运行时绑定变量

时间:2019-11-18 04:49:32

标签: java polymorphism overriding

我试图执行以下代码以清除运行时方法绑定的概念。我有三个类 Employee.java Programmer.java JPolymorphism.java 。我正在尝试从employee和Programmer类中打印方法。在方法编译是在运行时。通过这种方式,程序员应使用 programmer.name 进行打印,但应打印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);
    }

}

测试包

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();
    }
}

我无法理解 错误在哪里? ,因为方法在运行时绑定,而我的最后一行代码 programmer.name 是程序员类型和引用类型的类型是员工类型,那么根据概念,该行应弹出Prograamer,但同时也打印Employee。我在哪里做错了?

2 个答案:

答案 0 :(得分:2)

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

显然可以打印Employee

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

输出Employee,因为字段绑定发生在编译时,所以programmer.name引用了Employee.name字段,因为programmer被声明为Employee

emp.printName();

显然可以打印Employee

programmer.printName();

这将显示Employee,因为您正在调用Employee.printName()方法,该方法访问Employee.name字段,并且该方法尚未被子类Programmer覆盖。 / p>

为什么不覆盖它?因为 Programmer方法被命名为print,而不是printName 。如果您添加了@Override批注(如果您希望该方法重写超类方法),则编译器会告诉您您有问题。

如果将Programmer方法重命名为printName

  • 一个好的IDE会告诉您添加@Override批注。

  • programmer.printName()调用将打印Programmer

答案 1 :(得分:0)

代码的问题是,当您调用programmer.printName();时,它正在调用printName()类的Employee函数,其变量为name,其值是“员工”。

问题是,即使ProgrammerEmployee的子类,name类也无法访问Programmer类的变量Employee。在继承中,属性是从超类继承的,在这种情况下,EmployeeEmployee无法直接访问其子类的字段。因此,在完成programmer.printName();调用后,将调用printName()类的Employee方法,并打印值“ Employee”。

这样,由于other answer中所指出的功能没有覆盖,因此代码无法反映出运行时方法绑定的概念。