2016-12-01 86 views
0

我在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

为什么?为什么不在抽象类中定义一个“什么都不做”的版本,然后调用它,如果子类覆盖它,它们的版本会被调用? –

回答

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...*/) { 
    } 
} 
+0

我不想在父级创建“default”'spacialMethod',因为我不知道方法名是什么,我只能在运行时找到它...剂量this.getClass()。如果我没有在'Parent'类声明它,getMethod(“specialMethod”)'会工作吗? – nrofis

+1

@nrofis然后你有一个糟糕的设计。 –

+0

@nrofis:是的。这是一种替代方案,不是前面代码块的扩展。 'this.getClass()'获取实例的类,其中(在子类中)是子类。 –

0

除了从TJ克劳德你答案可以使用getDeclaredMethods来获取所有方法并调用专用之一。

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

只是为了记住'getDeclaredMethods'不返回继承的方法,也就是说,超类中声明的方法不会被返回。 –

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; 
    } 
}