From: wisberg Date: Wed, 6 Aug 2003 10:30:25 +0000 (+0000) Subject: double-dispatch example X-Git-Tag: V1_1_1~148 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=3b602a9080c98a55ba057287977eac71f4e15da8;p=aspectj.git double-dispatch example --- diff --git a/docs/sandbox/common/language/DoubleDispatch.java b/docs/sandbox/common/language/DoubleDispatch.java new file mode 100644 index 000000000..2d5a23f0a --- /dev/null +++ b/docs/sandbox/common/language/DoubleDispatch.java @@ -0,0 +1,81 @@ + + +package language; + +import org.aspectj.testing.Tester; + +/** @author Wes Isberg */ +public class DoubleDispatch { + + public static void main(String[] a) { + Worker worker = new Worker(); + worker.run((SuperType) new SubTypeOne()); + worker.run((SuperType) new SubTypeTwo()); + worker.run(new SuperType()); + Tester.checkAllEvents(); + } + static aspect A { + static int counter; + static { + Tester.expectEvent("language.SubTypeOne-1"); + Tester.expectEvent("language.SubTypeTwo-2"); + Tester.expectEvent("language.SuperType-3"); + } + before(Object o) : execution(void Worker.run(..)) && args(o) { + Tester.event(o.getClass().getName() + "-" + ++counter); + } + } +} + +// START-SAMPLE language-doubleDispatch Implementing double-dispatch + +/** + * By hypothesis, there is a working class with + * methods taking a supertype and subtypes. + * The goal of double-dispatch is to execute the + * subtype method rather than the supertype + * method selected when the compile-time + * reference is of the super's type. + */ +class Worker { + void run(SuperType t) {} + void run(SubTypeOne t) {} + void run(SubTypeTwo t) {} +} + +class SuperType {} +class SubTypeOne extends SuperType {} +class SubTypeTwo extends SuperType {} + +/** Implement double-dispatch for Worker.run(..) */ +aspect DoubleDispatchWorker { + + /** + * Replace a call to the Worker.run(SuperType) + * by delegating to a target method. + * Each target subtype in this method dispatches back + * to the subtype-specific Worker.run(SubType..) method, + * to implement double-dispatch. + */ + void around (Worker worker, SuperType targ): + !withincode(void SuperType.doWorkerRun(Worker)) && + target (worker) && call (void run(SuperType)) && + args (targ) { + targ.doWorkerRun(worker); + } + + void SuperType.doWorkerRun(Worker worker) { + worker.run(this); + } + + // these could be in separate aspects + void SubTypeOne.doWorkerRun(Worker worker) { + worker.run(this); + } + void SubTypeTwo.doWorkerRun(Worker worker) { + worker.run(this); + } +} + +// END-SAMPLE language-doubleDispatch + \ No newline at end of file diff --git a/docs/sandbox/sandbox-test.xml b/docs/sandbox/sandbox-test.xml index 494fa5672..332a4a9d1 100644 --- a/docs/sandbox/sandbox-test.xml +++ b/docs/sandbox/sandbox-test.xml @@ -62,6 +62,11 @@ + + + + +