简体   繁体   English

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

[英]call the same method name from instances different type

I have some libraries from external company, I want to use this API. 我有一些来自外部公司的库,我想使用此API。 I try to implement calling this API, my logic should call the same method name. 我尝试实现调用此API的方法,我的逻辑应调用相同的方法名称。 I have duplicate codes, I want to avoid to do this. 我有重复的代码,我想避免这样做。 I'm beginner and subjects like interfaces, polymorphism are little bit difficult to me. 我是初学者,界面,多态性等主题对我来说有点困难。

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

First of all I should mention that the methodology which you requested in your question is called "Duck Typing" . 首先,我要提到的是,您在问题中所要求的方法称为“鸭式打字” Generally this technology is possible in Java (see below the example) but it's not widely used in Java. 通常,该技术在Java中是可行的(请参见示例下方),但在Java中并未广泛使用。 There could be performance hits etc. It would be much better to introduce a proper inheritance/interface level instead. 可能会影响性能等。最好引入适当的继承/接口级别。

Also the provided example don't deal with exceptions properly etc. It's just a quick and quite dirty "demostration of the technology". 同样,所提供的示例未正确处理异常等。这只是一种快速且相当肮脏的“技术破坏”。 Feel free to adapt it for your needs. 随时根据您的需求进行调整。

It's Java7 (for multi-catch clauses, you may refactor this with ease). 它是Java7(对于多捕获子句,您可以轻松地重构它)。

ISomeIterface.java (it contains all common methods implemented by classes which are used in your "bad code"): 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: 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);
      }
    }
  }
}

And test class ReflectTest.java. 并测试ReflectTest.java类。 Notice that classes ReflectTest.Test and ReflectTest.Test2 has the same methods as ISomeInterface but don't implement it, they are completely independent from that interface and from each other. 注意,ReflectTest.Test和ReflectTest.Test2类具有与ISomeInterface相同的方法,但是没有实现,它们与该接口以及彼此完全独立。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM