覆盖Java方法

时间:2010-01-28 13:32:30

标签: java method-overriding

我是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();”更通用的使用当前类的名称。这可能吗?

6 个答案:

答案 0 :(得分:6)

如果您:

,该代码将输出B
(new B()).run();

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

已更新(编辑后)

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

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

希望有所帮助。

答案 1 :(得分:3)

我试过,将你的两个类放在两个文件中,它运行良好,输出“B”。我打电话给:

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

更新:也适用(因为它是相同的运行时实例):

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

答案 2 :(得分:2)

适合我。

这是我的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'。

答案 3 :(得分:1)

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

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

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

答案 4 :(得分:1)

我尝试了你的例子,我的输出是 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();
    }
}

答案 5 :(得分:1)

如果您的外部程序实例化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();

}