2012-03-19 88 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指令。