调用重载的方法,其中所有参数都实现相同的接口

dou*_*e07 1 java reflection overloading multiple-dispatch visitor-pattern

我的出发点如下:
- 我有一个方法,转换,我重载,根据传入的参数类型不同(参见transform(A a1,A a2)和transform(A a1,B b))在下面的例子中)
- 所有这些参数都实现了相同的接口X.

我想在所有实现X接口的各种对象上应用该转换方法.

我想到的是实现变换(X x1,X x2),它在应用变换的相关变量之前检查每个对象的实例.

虽然它有效但代码看起来很难看,我也担心评估这些各种instanceof和cast的性能开销.这是我用Java做的最好的转换,还是有更优雅和/或更有效的方法来实现相同的行为?

以下是印刷BA的一个简单的工作示例.我正在寻找有关如何改进该代码的示例.在我的真实代码中,我自然有更多的'transform'实现,而且没有一个像下面那样简单.

public class A implements X {
}

public class B implements X {
}

interface X {
}

public A transform(A a1, A a2) {
  System.out.print("A");
  return a2;
}

public A transform(A a1, B b) {
  System.out.print("B");
  return a1;
}

// Isn't there something better than the code below???
public X transform(X x1, X x2) {
  if ((x1 instanceof A) && (x2 instanceof A)) {
    return transform((A) x1, (A) x2);
  } else if ((x1 instanceof A) && (x2 instanceof B)) {
    return transform((A) x1, (B) x2);
  } else {
    throw new RuntimeException("Transform not implemented for "
            + x1.getClass() + "," + x2.getClass());
  }
}

@Test
public void trivial() {
  X x1 = new A();
  X x2 = new B();
  X result = transform(x1, x2);
  transform(x1, result);
}
Run Code Online (Sandbox Code Playgroud)

Jor*_*dão 5

访客模式为出发点.

如果您的层次结构发生了很大变化,则访问者模式会在整个范 在这种情况下,还要看非循环访客.

代码可能如下所示:

public interface X {
  void accept(XVisitor v);
}

public interface XVisitor { 
  void visit(A a);
  void visit(B b);
}

public class A implements X {
  public void accept(XVisitor v) {
    v.visit(this);
  }
}

public class B implements X {
  public void accept(XVisitor v) {
    v.visit(this);
  }
}
Run Code Online (Sandbox Code Playgroud)

然后你的算法进入这个类:

public class XTransformerVisitor implements XVisitor {
  private X result;
  private A first;
  public void visit(A a) {
    if (first == null) first = a;
    else result = a;
  }
  public void visit(B b) {
    if (first == null) throw new RuntimeException();
    result = first;
  }
  public X transform(X x1, X x2) {
    x1.accept(this);
    x2.accept(this);
    return result;
  }
}
Run Code Online (Sandbox Code Playgroud)