Overriding a Java Method

我只是一个虾纸丫 提交于 2019-12-23 10:22:40

问题


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?


回答1:


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.




回答2:


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();



回答3:


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'.




回答4:


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()



回答5:


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();
    }
}



回答6:


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();

}


来源:https://stackoverflow.com/questions/2154802/overriding-a-java-method

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!