abstract class ArithExpr { static ArithExpr e1 = new Sum(new Prod(new Const(5),new Const(7)),new Const(17)); static ArithExpr e2 = new Neg(e1); static ArithExpr e3 = new Prod(e1, e2); static ArithExpr e4 = new Prod(e3, e3); abstract int accept(AEVisitor v); static void test() { System.out.println(e1); System.out.println(e2); System.out.println(e3); System.out.println(e4); } public static void main(String[] args) { test(); } } class Const extends ArithExpr { int value; Const(int v) { value = v; } public String toString() { return Integer.toString(value); } int accept(AEVisitor v) { return v.forConst(this); } } class Sum extends ArithExpr { ArithExpr left,right; Sum(ArithExpr l, ArithExpr r) { left = l; right = r; } public String toString() { return "(" + left + "+" + right + ")"; } int accept(AEVisitor v) { return v.forSum(this); } } class Prod extends ArithExpr { ArithExpr left,right; Prod(ArithExpr l, ArithExpr r) { left = l; right = r; } public String toString() { return left + "*" + right; } int accept(AEVisitor v) { return v.forProd(this); } } class Neg extends ArithExpr { ArithExpr expr; Neg(ArithExpr e) { expr = e; } public String toString() { return "-" + expr; } int accept(AEVisitor v) { return v.forNeg(this); } } interface AEVisitor { int forConst(Const c); int forSum(Sum s); int forProd(Prod p); int forNeg(Neg n); }