Java 从不同类型的实例调用相同的方法名

Java 从不同类型的实例调用相同的方法名,java,dynamic,polymorphism,Java,Dynamic,Polymorphism,我有一些来自外部公司的库,我想使用这个API。我尝试实现调用这个API,我的逻辑应该调用相同的方法名。我有重复的代码,我想避免这样做。我是初学者,像接口、多态性这样的主题对我来说有点难 public void modPeople(Object person) { if (person instanceof com.company.persontype1) { com.company.persontype1 fireman = (com.company.persontype1) perso

我有一些来自外部公司的库,我想使用这个API。我尝试实现调用这个API,我的逻辑应该调用相同的方法名。我有重复的代码,我想避免这样做。我是初学者,像接口、多态性这样的主题对我来说有点难

public void modPeople(Object person)
{
 if (person instanceof com.company.persontype1)
 {
  com.company.persontype1 fireman = (com.company.persontype1) person; 
  String name = fireman.getName();

     if (name!=null ) {
     ...
      fireman.set_name();
      fireman.save();
     }

     permissions  = fireman.get_Permissions();
     ...
  permissions = fixperm (permissions);

  fireman.set_Permissions();
 };

 if (person instanceof com.company.persontype2)
 {
  com.company.persontype2 nurse = (com.company.persontype2) person; 
  String name = nurse.getName();

     if (name!=null ) {
     ...
      nurse.set_name();
      nurse.save();
     }

     permissions  = nurse.get_Permissions();
     ...
  permissions = fixperm (permissions);

  nurse.set_Permissions();
 };
}

首先,我要提到的是,你在问题中要求的方法称为。通常,这种技术在Java中是可行的,请参见下面的示例,但在Java中并未广泛使用。可能会影响性能等。最好引入适当的继承/接口级别

另外,所提供的示例没有正确地处理异常等。它只是对该技术的一个快速而肮脏的演示。您可以根据自己的需要随意调整它

它是Java7 for multi-catch子句,您可以轻松地重构它

ISomeIterface.java它包含由坏代码中使用的类实现的所有常用方法:

package org.test;

public interface ISomeInterface {
  public String getName();
  public void setName(String _name);
  public void save();
  // specify other common methods
}
ReflectCaller.java:

package org.test1;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
import java.util.NoSuchElementException;

import org.test.ISomeInterface;

public class ReflectCaller {

  private final Method[] methods = ISomeInterface.class.getDeclaredMethods();
  private final Map<Class<?>, Method[]> maps = new HashMap<Class<?>, Method[]>();

  public void inspectClass(Class<?> _clazz) throws NoSuchMethodException, SecurityException {
    final Method[] ms = new Method[methods.length];
    int i = 0;
    for(final Method m: methods) {
      ms[i] = _clazz.getMethod(m.getName(), m.getParameterTypes());
      i++;
    }
    maps.put(_clazz, ms);
  }

  public ISomeInterface wrapper(Object _obj) {
    final Method[] ms = maps.get(_obj.getClass());
    // To be replaced by guava's Preconditions.checkState()
    if (ms == null)
      throw new NoSuchElementException(String.format("Class %s is unregistered", _obj.getClass().getName()));
    return new SomeInterfaceImpl(_obj, ms);
  }

  private static class SomeInterfaceImpl implements ISomeInterface {
    private final Object obj;
    private final Method[] ms;

    public SomeInterfaceImpl(Object _obj, Method[] _ms) {
      ms = _ms;
      obj = _obj;
    }

    @Override
    public String getName() {
      try {
        return (String) ms[0].invoke(obj);
      } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
        throw new RuntimeException(e);
      }
    }

    @Override
    public void setName(String _name) {
      try {
        ms[1].invoke(obj, _name);
      } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
        throw new RuntimeException(e);
      }
    }

    @Override
    public void save() {
      try {
        ms[2].invoke(obj);
      } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
        throw new RuntimeException(e);
      }
    }
  }
}
persontype1和persontype2是否有可能与您需要的所有方法(如AbstractPersontype)共享一些公共类型?如果是这样,您可以使用此类型而不是对象。不幸的是,我没有AbstractPersonType和方法。我有超过10个人类型。当我看到代码时,我非常沮丧。这意味着,每种类型-com.company.persontype1,com.company.persontype2,…-是否直接从java.lang.Object类型派生?之间没有抽象层?也许是一个接口,它们都实现了?通常API在com.company.persontypeXXX类型上工作,我必须在系统中找到人并修复一些值。我的想法是使用Object,因为我想有一种方法可以修复person对象的整个类型。我发现有一种类型是护士和医生的父母,但它不是消防员的父母。此外,此父类型没有保存、设置\u权限等方法。
package org.test2;

import org.test.ISomeInterface;
import org.test1.ReflectCaller;

public class ReflectTest {
  private final ReflectCaller rc;
  ReflectTest(Class ... _classes) throws NoSuchMethodException, SecurityException {
    rc = new ReflectCaller();
    for(final Class c: _classes)
      rc.inspectClass(c);
  }

  void callSequence(Object _o) {
    // this function demonstrates the sequence of method calls for an object which has "compliant" methods
    ISomeInterface tw = rc.wrapper(_o);
    tw.setName("boo");
    System.out.printf("getName() = %s\n", tw.getName());
    tw.save();
  }

  public static class Test {
    public String getName() {
      System.out.printf("%s.getName()\n", getClass().getName());
      return "boo";
    }
    public void setName(String _name) {
      System.out.printf("%s.setName(%s)\n", getClass().getName(), _name);
    }
    public void save() {
      System.out.printf("%s.save()\n", getClass().getName());
    }
  }

  public static class Test2 {
    public String getName() {
      System.out.printf("%s.getName()\n", getClass().getName());
      return "boo2";
    }
    public void setName(String _name) {
      System.out.printf("%s.setName(%s)\n", getClass().getName(), _name);
    }
    public void save() {
      System.out.printf("%s.save()\n", getClass().getName());
    }
  }

  public static void main(String[] args) {
    ReflectTest rt;
    try {
      rt = new ReflectTest(Test.class, Test2.class);
    } catch (NoSuchMethodException | SecurityException e) {
      System.out.println(e);
      System.exit(2);
      return;
    }

    rt.callSequence(new Test());
    rt.callSequence(new Test2());
  }
}