【问题标题】:Java superclass instantiation calling subclass method, not sure whyJava超类实例化调用子类方法,不知道为什么
【发布时间】:2012-04-25 05:23:01
【问题描述】:

所以我遇到了一个类似这样的问题:

package com.blah.A_package;

public class A
{
    public void f() {
        g();
    }

    protected void g() {
        System.out.println("superclass g()");
    }
}

package com.blah.B_package;

public class B extends com.blah.A_package.A
{
    protected void g() {
        System.out.println("subclass g()");
    }
}

public static void main(String[] args)
{
    A scratch = new A();
    scratch.f();
}

运行时,它会打印出“子类 g()”而不是预期的“超类 g()”。

我们实际上是在创建超类和子类的对象(这是通过 jar 上的反射),将它们粘贴到地图中,然后根据需要将它们拉出,但我们已经通过打印出object.getClass().getName() 并看到我们实际上正在处理超类实例化。

无论如何,当我们运行应用程序时,由于某种原因,它使用的是方法的子类副本而不是超类,尽管对象是超类的实例(即,它甚至不应该知道子类方法) .这是我和我的同事不知道的已知事情吗?我们完全不知道为什么会发生这种情况。

【问题讨论】:

  • 你正在让一个类扩展一个包???我以前从未见过!
  • 这是完全无法运行的 java。函数返回类型在哪里???
  • 你的代码多处错误,请先更正:)
  • 一旦你有一个简短但完整的程序,它实际上工作并演示了问题,我相信你。在那之前,我会认为这是一个诊断错误......
  • 另一个包中你不会有一个名为AB的子类(不是B的原始超类)吗?

标签: java overriding subclass superclass


【解决方案1】:

简而言之,唯一可能导致这种情况的是运行时对象是 B 的一个实例,但您将其声明为 A。当调用该方法时,您的程序将开始查看它被调用的对象,然后沿着继承树向上工作。

附带说明,您缺少构造函数,您的 B 类扩展了一个包,并且您的方法没有返回类型。那是完全无效的Java。

【讨论】:

  • 我知道示例中的问题。这不是实际的代码。请忽略它们并专注于实际出了什么问题。正如我所说,我们通过打印出 obj.getClass().getName() 来验证它不是子类的实例化。
  • 我感冒了,抱歉刚才没闻到。
【解决方案2】:

可能导致这种混淆的一件事是有一个 B 的子类与其超类 (A) 同名但是 A 超类。

除此之外,它看起来像是一个分析错误。追溯你的步骤。一些想法:删除类 B 或使其不可实例化,然后重新引入并再次测试。

【讨论】:

  • B 没有子类,B 是 A 的唯一子类。我们用 obj.getClass().getName() 打印出完整的类名,它是有问题的超类正在使用,而不是子类或不同包中的某个类。
  • 但在您的分析中看起来仍然是一个错误。追溯你的步骤。一些想法:删除类B或使其不可实例化,然后重新引入并再次测试。
  • 我们实际上已将 B 重命名为完全不同的名称,但看到的行为相同。之后,我们将超类中的方法签名更改为不同的,并修改了对它的调用以包含添加的参数(以强制始终调用超类方法)并修复它,但显然不会作为解决方案,但问题仍然悬而未决。不幸的是,让它不可实例化不是一种选择。
猜你喜欢
  • 2015-09-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-04-16
  • 1970-01-01
  • 2018-08-22
  • 2023-01-12
  • 2015-03-01
相关资源
最近更新 更多