package jmultimethod; public class CarTest { interface CarElement {} class Wheel implements CarElement { private String name; Wheel(String name) { this.name = name; } String getName() { return this.name; } } class Engine implements CarElement {} class Body implements CarElement {} class Car { CarElement[] elements; public CarElement [] getElements() { return elements.clone(); } public Car() { this.elements = new CarElement[] { new Wheel("front left"), new Wheel("front right"), new Wheel("back left") , new Wheel("back right"), new Body(), new Engine()}; } } @Multi("visit") public void visitP(Wheel wheel, @V("print") String mode) { System.out.println("Visiting "+ wheel.getName() + " wheel"); } @Multi("visit") public void visitP(Engine engine, @V("print") String mode) { System.out.println("Visiting engine"); } @Multi("visit") public void visitP(Body body, @V("print") String mode) { System.out.println("Visiting body"); } @Multi("visit") public void visitP(Car car, @V("print") String mode) { System.out.println("\nVisiting car"); for(CarElement element : car.getElements()) { visit(element, mode); } System.out.println("Visited car"); } @Multi("visit") public void visitD(Wheel wheel, @V("do") String mode) { System.out.println("Kicking my "+ wheel.getName()); } @Multi("visit") public void visitD(Engine engine, @V("do") String mode) { System.out.println("Starting my engine"); } @Multi("visit") public void visitD(Body body, @V("do") String mode) { System.out.println("Moving my body"); } @Multi("visit") public void visitD(Car car, @V("do") String mode) { System.out.println("\nStarting my car"); for(CarElement element : car.getElements()) { visit(element, mode); } System.out.println("Started car"); } protected Multimethod mm = new Multimethod("visit", getClass()); public void visit(Object any, String mode) { mm.invoke(this, any, mode); } public void run() { Car car = new Car(); visit(car, "print"); visit(car, "do"); } static public void main(String[] args){ CarTest t = new CarTest(); t.run(); } }