【问题标题】:How does inheritance and polymorphism work in this situation?在这种情况下,继承和多态是如何工作的?
【发布时间】:2023-03-24 14:02:01
【问题描述】:

这是第一堂课

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 中的那个?毕竟doSomething()不是Project中的一个方法吗?或者当基类中有一个方法位于基类中的另一个方法中时,即使我们在另一个方法中,变量所引用的对象仍然决定将调用哪个方法调用?

现在,如果我们将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 修饰符)将不胜感激。

【问题讨论】:

标签: java inheritance polymorphism


【解决方案1】:

在 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 的公共版本。

【讨论】:

    【解决方案2】:

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

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

    你可以参考这个例子inheritance and polymorphism

    希望对你有帮助。

    【讨论】:

      【解决方案3】:

      对于方法的继承,使用这个模型:

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

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

      相反,Java 采用this,调用getClass(),然后如上所述获取方法列表。所以即使Project中的代码被执行,它仍然使用Project1列表中的方法。

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2020-09-26
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-08-20
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多