Java多态:非最终方法调用

时间:2014-12-07 03:22:30

标签: java polymorphism

//employee class
public class Employee {

protected String psrn;

public Employee(String n)
{
    psrn =n;
}

public String getPSRN()
{
    return ("Emp:"+psrn);
}

void computeSimilarity(Employee t)
{
    System.out.println("Emp::compute---"+t.getPSRN());
}

}

//student class


public class Student extends Employee{
public Student(String n) {
        super(n);
        // TODO Auto-generated constructor stub
    }

public String getPSRN()
{
    return("Std:"+psrn);
}
void computeSimilarity(Student t)
{
    System.out.println("Std::compute---"+t.getPSRN());
}
}

//tester class

public class Tester {

/**
 * @param args
 */
public static void main(String[] args) {
    // TODO Auto-generated method stub
Employee e0=new Employee("0");
Employee e=new Student("1");
Student s=new Student("2");

e.computeSimilarity(s);
s.computeSimilarity(e);
s.computeSimilarity(s);
s.computeSimilarity(e0);

}

}

输出结果是:

  

的Emp ::计算---标准:2

     

的Emp ::计算---标准:1

     

标准::计算---标准:2

     

的Emp ::计算---的Emp:0

但根据我的理解,它应该是

  

的Emp ::计算---标准:2

     

的Emp ::计算---标准:1

     

标准::计算---标准:2

     

标准::计算---的Emp:0

谁能告诉我哪里出错?

2 个答案:

答案 0 :(得分:1)

如果我读得正确,你会得到意想不到的结果

s.computeSimilarity(e0);

您的期望是会调用 Student.computeSimilarity(Student),但会调用 Employee.computSimiarity(Employee)

调用 Employee.computSimiarity(Employee)的原因是因为Student类中的computeSimilarity方法不是基类方法的重写。

要覆盖方法,您必须保持确切的签名。

void computeSimilarity(Employee t)

void computeSimilarity(Student s)

是不同的签名。

========================

建议:使用Java的@Override注释。如果将此注释放在要作为覆盖的方法上,编译器将确保这种情况。如果你把这个注释放在Student类的方法上,编译器就会给你一个错误信息。

所以在你的学生班上,你会有:

@Override
void computeSimilarity(Student t) {
    System.out.println("Std::compute---"+t.getPSRN());
}

编译器会将其标记为错误,您可以通过以下更改来纠正错误:

@Override
void computeSimilarity(Employee t) {
    System.out.println("Std::compute---"+t.getPSRN());
}

然后你会有所期望的行为。

答案 1 :(得分:0)

您在Employee中有以下方法:

void computeSimilarity(Employee t)

和学生中的这个:

void computeSimilarity(Student t)

第二种方法不会覆盖第一种方法。它是一个完全独立的方法,碰巧具有相同的名称。

为什么不呢?想象一下,如果它确实覆盖了。那么这段代码就可以了:

class Employee {
    void print(Object o) {
        System.out.println(o);
    }
}
class Student extends Employee {
    void print(String s) {
        System.out.println(s.length());
    }
}
public class Main {
    public static void main(String[] args) {
        Employee e = new Student();
        e.print(e);
    }
}

并以某种方式使用print(String s)的参数调用Student。这不应该被允许发生 - 实际上,它 不允许发生,因为Student中的方法不会覆盖Employee中的方法。 / p>

在某些语言中,如果参数是字符串,则上面的代码将调用Student方法,否则将调用Employee方法。 Java不这样做。