调用未知子类的方法

时间:2016-12-01 13:18:09

标签: java reflection

我在Java中有抽象类。我想用反射来调用他的子类的特定方法(如果它存在)。

public abstract class Parent {
    public void doIt(String functionName) {
        if (the caller class have method called as functionName parameter) {
            call it
        }
    }
}

public class Child extends Parent{
    public void spacialMethod() {
        System.out.println("Child special method called");
    }
}

public class Child2 extends Parent{
    // Empty
}

所以,如果我将运行该代码:

Child child = new Child();
child.doIt("spacialMethod"); // Will print the text
Child2 child2 = new Child2();
child2.doIt("spacialMethod"); // Nothing will happened

如果当前子类具有名为“specialMethod”的方法,我如何检查父类?

3 个答案:

答案 0 :(得分:5)

可能做你所要求的事情(见答案的结尾),但如果没有充分理由的话,设计很差。

如果您不需要在运行时确定名称,我会在Parent中将方法定义为什么都不做,然后调用它;如果子类重写它,那很好。

public abstract class Parent {
    public void doIt() {
        this.specialMethod();
    }
    public void spacialMethod() {
        // Do nothing
    }
}

public class Child extends Parent{
    @Override
    public void spacialMethod() {
        // Optionally call super.specialMethod() here
        System.out.println("Child special method called");
    }
}

public class Child2 extends Parent{
    // Empty
}

但是如果你真的希望用反射来做(例如,你需要在运行时定义名称),那就不难了:

// Not recommended if you can avoid it
public void doIt() {
    try {
        this.getClass().getMethod("specialMethod").invoke(this);
    }
    catch (/*...appropriate exception handling...*/) {
    }
}

答案 1 :(得分:0)

除了TJ Crowder的答案,您可以使用getDeclaredMethods获取所有方法并调用特殊

 public void doIt() {
        Method[] methods = getClass().getDeclaredMethods();
        for(Method method : methods){
          if(method.getName().contains("special"){
             method.invoke(this);
          }
        }
    }

答案 2 :(得分:0)

只是一个没有反思的例子:

有一种专门为每个子类实现或未实现的“访问者”;实施时,它会委托给孩子所需的方法。

请注意,与下面的示例不同,访问者实现可以在类本身外部,因此孩子甚至不必知道它将如何被访问。

public interface SpecialOpAccessor {
  void doIt();
}

public abstract class Parent {
    protected SpecialOpAccessor accessor;

    public void doIt() {
       if ( accessor != null ) {
         accessor.doIt();
       }
    }
}

public class Child extends Parent{

    public Child() {
      super();
      this.accessor = new SpecialOpAccessor() {
         @Override
         public void doIt() {
           Child.this.spacialMethod();
         }
      }
    }

    public void spacialMethod() {
        System.out.println("Child special method called");
    }
}

public class Child2 extends Parent{
    public Child() {
      super();
      this.accessor = null;
    }
}