在这种情况下,继承和多态如何工作?

时间:2013-11-07 15:39:47

标签: java inheritance polymorphism

这是第一堂课

package test;

public class Project {

public void doSomething (String stuff) {

    writeStuff();
    whichProject(stuff);

}

public void writeStuff(){

    System.out.println("This is stuff");

}


public void whichProject(String stuff){

    System.out.println("This is a random project " + stuff);

}

}

这是派生类

package test;

public class Project1 extends Project{

public void whichProject(String stuff){

    System.out.println("Coding project number one: " + stuff);

}

public static void main(String[] args) {

    Project project = new Project1();

    project.doSomething("stuff");

}

}

运行Project1时,输出结果为:

This is stuff
Coding project number one: stuff

为什么它在Project1中调用whichProject()而不在Project中调用?{1}}?毕竟,Project doSomething()不是一个方法吗?或者当基类中的另一个方法中的基类中有一个方法时,变量引用的对象仍然确定即使我们在另一个方法内部也会调用哪个方法调用?

现在,如果我们将whichProject()的修饰符更改为private,那么现在该类是

package test;

public class Project {

public void doSomething (String stuff) {

    writeStuff();
    whichProject(stuff);

}

public void writeStuff(){

    System.out.println("This is stuff");

}


private void whichProject(String stuff){

    System.out.println("This is a random project " + stuff);

}

}

输出变为:

This is stuff
This is a random project stuff

所以现在调用Project中的whichProject()方法而不是Project1,即使变量引用了Project1的对象。在这种情况下,我完全不了解发生了什么。对于这两种情况(whichProject()使用public修饰符和whichProject()使用private修饰符)的解释将不胜感激。

3 个答案:

答案 0 :(得分:3)

在Java中,所有方法都是虚拟的。

虚方法是可以在派生类中重写的方法,只要子类中的版本具有相同的签名(返回类型和参数)。

因此,在Project和Project1的原始版本中,如果您有Project1,Project1的public void whichProject(String stuff)版本将被称为,即使是Project方法中的代码

但是,如section 8.4.8.3 of the Java Language Specification中所述,私有方法无法覆盖:

  

请注意,在这些术语的技术意义上,无法隐藏或覆盖私有方法。这意味着子类可以在其一个超类中声明一个与私有方法具有相同签名的方法,并且不要求这种方法的返回类型或throws子句与该方法中的私有方法具有任何关系。超类。

因此,当Project doSomthing内的代码调用whichProject时,它会调用Project的私有版本而不是Project1的公共版本。

答案 1 :(得分:1)

继承遵循自下而上的方法。

所以writeProject()使用来自超类,whichProject(stuff)来自基类。

您可以参考此示例inheritance and polymorphism

希望它有所帮助。

答案 2 :(得分:1)

对于方法的继承,请使用此模型:

  1. 收集当前班级中的所有方法。
  2. 从超级类中添加可见的方法(即不是private),到目前为止还没有看到。
  3. 将此列表添加到继承列表中最顶层的类
  4. 调用方法时,Java知道实例的类型。想象一下,this作为不可见的方法参数传递给每个方法。通过查看定义方法的类来解决方法。

    相反,Java需要this,调用getClass(),然后获取上述方法列表。因此,即使执行Project中的代码,它仍会使用Project1列表中的方法。

    当您创建方法private时,这会发生变化。私有方法无法覆盖,它们根本不会显示在上面的列表中。相反,Java插入代码直接调用它而不查看列表。