2

这是第一堂课

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

为什么它whichProject()在 Project1 中调用而不是在 Project 中调用?毕竟,不是doSomething()Project中的方法吗?或者当基类中有一个方法位于基类中的另一个方法中时,即使我们在另一个方法中,变量所引用的对象仍然决定将调用哪个方法调用?

现在,如果我们改变 to 的修饰符,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

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

4

3 回答 3

3

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

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

因此,在 Project 和 Project1 的原始版本中,如果您有一个 Project1,则即使从 Project 的方法中的代码中public void whichProject(String stuff)也会调用Project1 的版本。

但是,如Java Language Specification 的第 8.4.8.3 节所述,私有方法不能被覆盖:

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

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

于 2013-11-07T16:29:26.513 回答
1

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

  1. 收集当前类中的所有方法。
  2. 添加来自超类的方法,这些方法是可见的(即不可见private)并且您到目前为止还没有看到。
  3. 将此列表添加到继承列表中的最顶层类

调用方法时,Java 知道实例的类型。想象一下,this它作为不可见的方法参数传递给每个方法。方法不是通过查看定义方法的类来解决的。

取而代之的是,Java 接受this、调用getClass()然后获取如上所述的方法列表。因此,即使Project执行了 in 中的代码,它仍然使用列表中的方法Project1

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

于 2013-11-07T15:52:44.573 回答
1

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

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

你可以参考这个例子继承和多态

希望能帮助到你。

于 2013-11-07T15:47:54.977 回答