重写 Java 方法

发布于 2024-08-19 19:54:47 字数 667 浏览 3 评论 0原文

我是 Java 新手,我已经阅读了一些有关重写方法的教程,但我正在查看的示例并未按我预期的方式工作。例如,我有代码:

public class A{
    public void show(){
        System.out.println("A");
    }
    public void run(){
        show();
    }
    public static void main( String[] arg ) {
        new A().run();
    }
}
public class B extends A{
    @Override
    public void show(){
        System.out.println("B");
    }
}

当我实例化并调用 B.run() 时,我希望看到“B”输出。然而,我看到的是“A”。我做错了什么?

编辑:是的,这些类位于两个单独的文件中。为了简洁起见,它们一起显示。

编辑:我不确定 B 是如何实例化的,因为它是由第三方程序使用类加载器完成的。

编辑:有关第三方程序的更多信息。它首先调用 A.main(),我最初没有显示它(抱歉)。我假设我需要制作“new A().run();”使用当前类的名称更通用。这可能吗?

I'm new to Java, and I've read over some tutorials on overriding methods, but an example I'm looking at isn't working the way I expect. For example, I have the code:

public class A{
    public void show(){
        System.out.println("A");
    }
    public void run(){
        show();
    }
    public static void main( String[] arg ) {
        new A().run();
    }
}
public class B extends A{
    @Override
    public void show(){
        System.out.println("B");
    }
}

When I instantiate and call B.run(), I would expect to see "B" outputted. However, I see "A" instead. What am I doing wrong?

Edit: Yes, the classes are in two separate files. They're shown together for brevity.

Edit: I'm not sure how B is being instantiated, as it's being done by a third-party program using a classloader.

Edit: More info on the third-party program. It starts by calling A.main(), which I didn't initially show (sorry). I'm assuming I need to make "new A().run();" more generic to use the name of the current class. Is that possible?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

风吹短裙飘 2024-08-26 19:54:47

如果您满足以下条件,该代码将输出 B

(new B()).run();

无论问题是什么,它都不在您引用的代码中。

已更新(编辑后)

如果第三方程序正在调用 A.main(),则您在 B 中无能为力(合理) > 会将其自身注入到 A 中。只要 A.main 正在执行 new A().run(),它就会有一个 A 的实例,而不是一个实例B。没有“当前类名”可供使用,或者如果有(取决于您的观点),它是 A,而不是 B

您必须让第三方程序以某种方式调用 B,而不是 A,或者直接修改 A(例如,完全摆脱 B)。您不想想要修改A以使其使用B;这将它与后代紧密地联系在一起,使得它们之间的分离基本上毫无意义。

希望有帮助。

That code will output B if you:

(new B()).run();

Whatever the problem is, it's not in the code you've quoted.

Updated (after your edit)

If the third-party program is calling A.main(), there's nothing (reasonable) you can do in B that will inject itself into A. As long as A.main is doing new A().run(), it's going to have an instance of A, not an instance of B. There's no "current class name" to use, or if there is (depends on your point of view), it's A, not B.

You'll have to get the third-party program to call B in some way, rather than A, or just modify A directly (e.g., getting rid of B entirely). You do not want to modify A to make it use B; that tightly binds it to a descendant and makes the separation between them largely pointless.

Hope that helps.

一梦等七年七年为一梦 2024-08-26 19:54:47

我尝试将两个类放入两个文件中,效果很好,输出“B”。我调用:

 B b = new B();
 b.run();

更新:也可以作为(因为它是相同的运行时实例):

 A a = new B();
 a.run();

I tried, putting your two classes in two files, and it worked nicely, outputting "B". I called :

 B b = new B();
 b.run();

UPDATED : Also works as (because it is the same runtime instance):

 A a = new B();
 a.run();
眼趣 2024-08-26 19:54:47

对我有用。

这是我的 A 和 B 代码:

package so;

public class A{
    public void show(){
        System.out.println("A");
    }
    public void run(){
        show();
    }
}

class B extends A{
    @Override
    public void show(){
        System.out.println("B");
    }
}

这是我的入口点:

package so;

public class EntryPoint {

    public static void main(String[] args) {
        B b = new B();
        b.run();
    }
}

它打印出“B”。

Works for me.

Here's my code for A and B:

package so;

public class A{
    public void show(){
        System.out.println("A");
    }
    public void run(){
        show();
    }
}

class B extends A{
    @Override
    public void show(){
        System.out.println("B");
    }
}

Here's my entry point:

package so;

public class EntryPoint {

    public static void main(String[] args) {
        B b = new B();
        b.run();
    }
}

It prints out 'B'.

司马昭之心 2024-08-26 19:54:47

这取决于实例化。试试这个:

 A v1 = new A();
 A v2 = new B();
 B v3 = new A();
 B v4 = new B();

 v1.run()
 v2.run()
 v3.run()
 v4.run()

It depends of instantiating. Try this:

 A v1 = new A();
 A v2 = new B();
 B v3 = new A();
 B v4 = new B();

 v1.run()
 v2.run()
 v3.run()
 v4.run()
今天小雨转甜 2024-08-26 19:54:47

我尝试了你的例子,我的输出是B

你是如何实例化的?这是我运行的确切代码。

public class Test {
    public static class A {
        public void show() {
            System.out.println("A");
        }

        public void run() {
            show();
        }
    }

    public static class B extends A {
        @Override
        public void show() {
            System.out.println("B");
        }
    }

    public static void main(String args[]) {
        A a = new B();

        a.run();
    }
}

I tried your example and my output was B.

How are you instantiating? Here's the exact code I ran.

public class Test {
    public static class A {
        public void show() {
            System.out.println("A");
        }

        public void run() {
            show();
        }
    }

    public static class B extends A {
        @Override
        public void show() {
            System.out.println("B");
        }
    }

    public static void main(String args[]) {
        A a = new B();

        a.run();
    }
}
原谅我要高飞 2024-08-26 19:54:47

如果您的外部程序实例化 A,您将拥有 A,而不是 B。

但是您可以尝试类似的操作,使用一些反射,并将“com.mypackage.A”或“com.mypackage.B”作为参数传递给您的程序。

使用此代码(缺少异常捕获),您将能够根据您传递的字符串参数打印“A”或“B”。

public static void main( String[] arg ) {
    String className = arg[0];
    Class myClass  = Class.forName(className);
    Constructor cons = myClass.getConstructor(new Class[0]);
    A myObject = (A) cons.newInstance(new Object[0]);
    myObject.show();

}

If your external program instantiates A, you will have A, not B.

But you can try something like this, using some reflection, and pass "com.mypackage.A" or "com.mypackage.B" as arguments to your program.

With this code (exception catch missing), you will be able to print "A" or "B" depending on the string parameter that you pass.

public static void main( String[] arg ) {
    String className = arg[0];
    Class myClass  = Class.forName(className);
    Constructor cons = myClass.getConstructor(new Class[0]);
    A myObject = (A) cons.newInstance(new Object[0]);
    myObject.show();

}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文