You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

DoubleDispatch.java 2.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  1. package language;
  2. import org.aspectj.testing.Tester;
  3. /** @author Wes Isberg */
  4. public class DoubleDispatch {
  5. public static void main(String[] a) {
  6. Worker worker = new Worker();
  7. worker.run((SuperType) new SubTypeOne());
  8. worker.run((SuperType) new SubTypeTwo());
  9. worker.run(new SuperType());
  10. Tester.checkAllEvents();
  11. }
  12. static aspect A {
  13. static int counter;
  14. static {
  15. Tester.expectEvent("language.SubTypeOne-1");
  16. Tester.expectEvent("language.SubTypeTwo-2");
  17. Tester.expectEvent("language.SuperType-3");
  18. }
  19. before(Object o) : execution(void Worker.run(..)) && args(o) {
  20. Tester.event(o.getClass().getName() + "-" + ++counter);
  21. }
  22. }
  23. }
  24. // START-SAMPLE language-doubleDispatch Implementing double-dispatch
  25. /**
  26. * By hypothesis, there is a working class with
  27. * methods taking a supertype and subtypes.
  28. * The goal of double-dispatch is to execute the
  29. * subtype method rather than the supertype
  30. * method selected when the compile-time
  31. * reference is of the super's type.
  32. */
  33. class Worker {
  34. void run(SuperType t) {}
  35. void run(SubTypeOne t) {}
  36. void run(SubTypeTwo t) {}
  37. }
  38. class SuperType {}
  39. class SubTypeOne extends SuperType {}
  40. class SubTypeTwo extends SuperType {}
  41. /** Implement double-dispatch for Worker.run(..) */
  42. aspect DoubleDispatchWorker {
  43. /**
  44. * Replace a call to the Worker.run(SuperType)
  45. * by delegating to a target method.
  46. * Each target subtype in this method dispatches back
  47. * to the subtype-specific Worker.run(SubType..) method,
  48. * to implement double-dispatch.
  49. */
  50. void around (Worker worker, SuperType targ):
  51. !withincode(void SuperType.doWorkerRun(Worker)) &&
  52. target (worker) && call (void run(SuperType)) &&
  53. args (targ) {
  54. targ.doWorkerRun(worker);
  55. }
  56. void SuperType.doWorkerRun(Worker worker) {
  57. worker.run(this);
  58. }
  59. // these could be in separate aspects
  60. void SubTypeOne.doWorkerRun(Worker worker) {
  61. worker.run(this);
  62. }
  63. void SubTypeTwo.doWorkerRun(Worker worker) {
  64. worker.run(this);
  65. }
  66. }
  67. // END-SAMPLE language-doubleDispatch