2012-03-19 38 views
3
其实例

请考虑下面的代码展示继承和反射:调用超类方法,而无需使用反射

/*Parent class*/ 

    package basics; 

    public class Vehicle { 

     private void parentPrivateMethod() { 
      System.out.println("This is the child private method"); 
     } 

     public void print() { 
      System.out.println("This is a Vehicle method"); 
     } 

     public void overrideThisMethod() { 
      System.out.println("Parent method"); 
     } 

    } 


    /*Child class*/ 

    package basics; 

    public class Car extends Vehicle { 

     private void childPrivateMethod() { 
      System.out.println("This is the child private method"); 
     } 

     public String returnCarName() { 
      return "Manza"; 
     } 

     @Override 
     public void overrideThisMethod() { 
      //super.overrideThisMethod();/*NOTE THIS*/ 
      System.out.println("Child method"); 
     } 

    } 


    /*Tester class*/ 
    package basics; 

    import java.lang.reflect.InvocationTargetException; 
    import java.lang.reflect.Method; 

    public class NewTester { 

     /** 
     * @param args 
     * @throws NoSuchMethodException 
     * @throws SecurityException 
     * @throws InvocationTargetException 
     * @throws IllegalAccessException 
     * @throws IllegalArgumentException 
     * @throws InstantiationException 
     */ 
     public static void main(String[] args) throws SecurityException, 
       NoSuchMethodException, IllegalArgumentException, 
       IllegalAccessException, InvocationTargetException, InstantiationException { 
      // TODO Auto-generated method stub 

      Car carInstance = new Car(); 

      /* Normal method invocation */ 
      carInstance.overrideThisMethod(); 

      /* Reflection method invocation */ 
      Method whichMethod = Car.class.getSuperclass().getMethod(
        "overrideThisMethod", null); 
      whichMethod.invoke(carInstance, null); 

      /* Work-around to call the superclass method */ 
      Method superClassMethod = Car.class.getSuperclass().getMethod(
        "overrideThisMethod", null); 
      superClassMethod.invoke(Car.class.getSuperclass().newInstance(), null); 
     } 

    } 

输出(与“请注意,这”部分评论)是:

 Child method 
     Child method 
     Parent method 

在情况下,'NOTE THIS'部分未被评论,超类方法将被调用,给出输出:

 Parent method 
     Child method 
     Parent method 
     Child method 
     Parent method 

当Car的一个实例被创建时,Vehicle的构造函数首先运行。因此,我相信,Vehicle的一个实例也被创建,其参考Car实例通过“超级”保存。

问题: 我怎样才能调用“overrideThisMethod”的超类版本不使用/ *变通来调用父类的方法* /?

我在这里忽略了一些东西/在这里做出错误的假设?

+4

omg,为什么在这个世界上你会想要那个? – scibuff 2012-03-19 14:26:21

+0

in-sanity的回合:P 我想知道是否可以调用super.someOverridenMethod(),为什么不通过反射? – 2012-03-19 14:27:34

+0

这违背了公共,受保护和私人修饰符的全部观点。只调用你有权访问的方法。如果您需要访问其他方法,则请开发人员为您拓宽范围。如果他们不这样做,那就建立自己的班级。 (提示:复制和粘贴效果很好) – emory 2012-03-19 14:44:08

回答

0

如果您需要运行超类公用方法,请从超类的实例中调用它。如果你想从孩子中调用父方法,那么它不应该首先被覆盖。

Vehicle v = new Vehicle(); 
v.overrideThisMethod(); 
3

当创建Car的实例,车辆的构造函数先运行。因此,我相信,Vehicle的一个实例也被创建,其参考Car实例通过“超级”保存。

这不是很正确;只有一个对象被创建。 Vehicle的构造函数运行是因为它是Vehicle的一个实例,也是Car的一个实例。没有单独的车辆对象,并且super不是对象引用而是关键字。例如,您不能将super作为参数传递给方法。

关键字super允许您告诉编译器,您希望从超类中调用方法,而不检查该方法是否在子类中被重写。为了做到这一点,编译器用invokespecial JVM指令生成方法调用。通常编译器会发出一个invokevirtual指令。