反射

2012-03-19 14 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); 
     } 

    } 

(一部のコメント「これはNOTE」との)出力は次のとおりです。で

 Child method 
     Child method 
     Parent method 

「NOTE THIS」部分はコメントされず、スーパークラスメソッドが呼び出され、出力が得られます。

Carのインスタンスが作成されると、Vehicleのコンストラクタが最初に実行されます。したがって、私は、Carインスタンスが 'super'を介して保持する、Vehicleのインスタンスも作成されると信じています。

質問: はどのように私は/ *回避策スーパークラスのメソッドを呼び出すを使用せずに「overrideThisMethod」のスーパークラスバージョンを呼び出すことができますか* /?

私はここで何か見落としているか間違った仮定をしていますか?

+4

omg、なぜ世界であなたはこれを望んでいますか? – scibuff

+0

Bouts of in sanity:P super.someOverridenMethod()を呼び出せるかどうか、私は反射を経由していないのだろうか? –

+0

これは、public、protected、およびprivateの修飾子がある点全体に逆行します。アクセス権のあるメソッドのみを呼び出します。追加のメソッドにアクセスする必要がある場合は、開発者にスコープを広げるよう依頼してください。彼らがそれをしないなら、あなた自身のクラスを構築してください。 (ヒント:コピー&ペーストがうまくいきます) – emory

答えて

0

スーパークラスパブリックメソッドを実行する必要がある場合は、スーパークラスのインスタンスから呼び出す必要があります。親メソッドを子から呼び出す場合は、最初にオーバーライドしてはいけません。車のインスタンスが作成されると

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

、車両のコンストラクタは最初に実行されます。したがって、私は、Carインスタンスが 'super'を介して保持する、Vehicleのインスタンスも作成されると信じています。

これは正しくありません。 1つのオブジェクトのみが作成されます。 Vehicleのコンストラクタは、VehicleだけでなくCarのインスタンスでもあるため、実行されます。別のVehicleオブジェクトはありません。superはオブジェクト参照ではなくキーワードです。たとえば、superをメソッドに引数として渡すことはできません。

キーワードsuperを使用すると、メソッドがサブクラスでオーバーライドされていないかどうかをチェックせずに、スーパークラスからメソッドを呼び出すようにコンパイラに指示できます。これを行うために、コンパイラはinvokespecial JVM命令を使用してメソッド呼び出しを生成します。通常、コンパイラはinvokevirtual命令を発行します。

関連する問題